<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sean Jordan &#187; PHP</title>
	<atom:link href="http://seanjordan.me/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://seanjordan.me</link>
	<description>supernerd</description>
	<lastBuildDate>Wed, 25 Aug 2010 06:04:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Parse and Clean Query Strings with PHP</title>
		<link>http://seanjordan.me/2010/03/parse-and-clean-query-strings-with-php/</link>
		<comments>http://seanjordan.me/2010/03/parse-and-clean-query-strings-with-php/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 17:27:36 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=314</guid>
		<description><![CDATA[I wrote a quick, useful function in PHP to parse a query string, strip out dirty key(s), and return the cleaned query string. The function expects two parameters $dirty &#8211; a string, or an array of strings. These are the names of the variables that will be stripped out. $qs &#8211; OPTIONAL &#8211; The source [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote a quick, useful function in PHP to parse a query string, strip out dirty key(s), and return the cleaned query string.</p>
<p>The function expects two parameters</p>
<ol>
<li>$dirty &#8211; a string, or an array of strings.  These are the names of the variables that will be stripped out.</li>
<li>$qs &#8211; OPTIONAL &#8211; The source to use as the query string.  If not provided, the $_SERVER['QUERY_STRING'] variable is used</li>
</ol>
<p>The function returns a string in the format</p>
<p>var1=value1&#038;var2=value2&#8230;</p>
<pre name="code" class="php">
function clean_query_string($dirty, $qs = false) {
    //default to the server query string if none is provided
    $qs = ($qs) ? $qs : $_SERVER['QUERY_STRING'];

    // parse the query string as an array, writing it
    // down as a string as we go
    $clean = "";
    foreach(explode("&#038;", $qs) as $var) {
        $t = explode("=", $var);
        if( !in_array($t[0], (array)$dirty) ) {
            $clean .= "{$t[0]}={$t[1]}&#038;";
        }
    }

    //trim the trailing ampersand
    return trim($clean, "&#038;");
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2010/03/parse-and-clean-query-strings-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Variable variables in PHP</title>
		<link>http://seanjordan.me/2010/03/variable-variables-in-php/</link>
		<comments>http://seanjordan.me/2010/03/variable-variables-in-php/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 08:00:06 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=168</guid>
		<description><![CDATA[Well, after a couple month hiatus, I guess it is time to throw up another post. I was up working on a project, and came across a completely valid usage of variable variables, and felt it might be worth making a post, because it is kind of fun. At first glance, &#8220;variable variables&#8221; seemed pretty [...]]]></description>
			<content:encoded><![CDATA[<p>Well, after a couple month hiatus, I guess it is time to throw up another post.  I was up working on a project, and came across a completely valid usage of variable variables, and felt it might be worth making a post, because it is kind of fun.</p>
<p>At first glance, &#8220;variable variables&#8221; seemed pretty pointless to me.  Surely they had a place somewhere, but I guess that&#8217;s just not how I write code.  The best use I could think of was a pointless, but stupid-fun script, like this:</p>
<pre name="code" class="php">
$a = "hello world";
$b = "a";
$c = "b";
$d = "c";
$e = "d";
$f = $$$$$e;
</pre>
<p>Perhaps, for this example I&#8217;m about to use, there is a better way of accomplishing the task (I can think of other methods, but can argue which is &#8220;better&#8221;).  My task was to feed a function the numerical representation of a month, and spit back the textual representation, adhering to preferred formatting.  So I wrote a function that has a couple hard-coded lookup arrays, named after the $format parameter.  The function is pretty well self-explanatory:</p>
<pre name="code" class="php">
function getMonth($i, $format = 'F') {
    $F = array(
        1 => "January",
        2 => "February",
        3 => "March",
        4 => "April",
        5 => "May",
        6 => "June",
        7 => "July",
        8 => "August",
        9 => "September",
       10 => "October",
       11 => "November",
       12 => "December",
    );

    $M = array(
        1 => "Jan",
        2 => "Feb",
        3 => "Mar",
        4 => "Apr",
        5 => "May",
        6 => "Jun",
        7 => "Jul",
        8 => "Aug",
        9 => "Sep",
       10 => "Oct",
       11 => "Nov",
       12 => "Dec",
    );

    $format = strtoupper($format);

    if($format != 'F' &#038;&#038; $format != 'M') {
        $format = 'F';
    }

    if($i > 12 || $i < 1) {
        return false;
    }

    $source = $$format;
    return $source[$i];
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2010/03/variable-variables-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>just another php hacker</title>
		<link>http://seanjordan.me/2009/12/just-another-php-hacker/</link>
		<comments>http://seanjordan.me/2009/12/just-another-php-hacker/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 01:57:45 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=148</guid>
		<description><![CDATA[After reading about the Just Another Perl Hacker code snippets on Wikipedia, I was pretty intrigued. The only problem is, I hate Perl. So, here is my version: just another php hacker. I cleaned the code up a little bit here for readability (which is against the point, I guess). foreach(explode("2","1152117298211521162114") as $z) { $h [...]]]></description>
			<content:encoded><![CDATA[<p>After reading about the <a href="http://en.wikipedia.org/wiki/JAPH">Just Another Perl Hacker</a> code snippets on Wikipedia, I was pretty intrigued.  The only problem is, I hate Perl.  So, here is my version: just another php hacker.</p>
<p>I cleaned the code up a little bit here for readability (which is against the point, I guess).</p>
<pre name="code" class="php">
foreach(explode("2","1152117298211521162114") as $z) {
	$h .= chr($z);
}

$f = (string)(2*19*227*11489);

$q = chr($h($f,(int)$f[3],(int)$f[2]+1)).chr($h($f,(int)$f[2]+1,(int)$f[0]/3)).chr($h($f,(int)$f[strlen($f)-1]+1,(int)$f[0]/3));

$z = eval("\$u=".$q."(".str_replace("3",").$q(","117311031153101311431053973108310531223101").");");

$w = "a:23:{i:0F106F1F11F2F-2F3F1F4F-84F5F65F6F13F7F1F8F5F9F-12F10F-3F11F13F12F-82F13F80F14F-8F15F8F16F-80F17F72F18F-7F19F2F20F8F21F-6F22F13;}";

$b = str_replace("F",";i:", $w);

foreach($u($b) as $c) {
	echo($q($s+=$c));
}
</pre>
<p>Here is the more obfuscated text:</p>
<div class="code-section" style="overflow:auto; ">
<pre>
foreach(explode("2","1152117298211521162114")as$z){$h.=chr($z);}$f=(string)(2*19*227*11489);$q=chr($h($f,(int)$f[3],(int)$f[2]+1)).chr($h($f,(int)$f[2]+1,(int)$f[0]/3)).chr($h($f,(int)$f[strlen($f)-1]+1,(int)$f[0]/3));$z=eval("\$u=".$q."(".str_replace("3",").$q(","117311031153101311431053973108310531223101").");");$b=str_replace("F",";i:","a:23:{i:0F106F1F11F2F-2F3F1F4F-84F5F65F6F13F7F1F8F5F9F-12F10F-3F11F13F12F-82F13F80F14F-8F15F8F16F-80F17F72F18F-7F19F2F20F8F21F-6F22F13;}");foreach($u($b)as$c){echo($q($s+=$c));}
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2009/12/just-another-php-hacker/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Export to spreadsheet with PHP</title>
		<link>http://seanjordan.me/2009/12/export-to-spreadsheet-with-php/</link>
		<comments>http://seanjordan.me/2009/12/export-to-spreadsheet-with-php/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 07:41:00 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=144</guid>
		<description><![CDATA[With PHP, it is extremely simple to create a file that can be interpreted by speadsheet programs, such as Excel or OpenOffice.org. When you think about what this really means, it should be clear how simple it is. We&#8217;ll do this with by created a CSV file. CSV stands for Comma-Separated Values. So basically, we&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>With PHP, it is extremely simple to create a file that can be interpreted by speadsheet programs, such as Excel or OpenOffice.org.</p>
<p>When you think about what this really means, it should be clear how simple it is.  We&#8217;ll do this with by created a CSV file.  CSV stands for Comma-Separated Values.  So basically, we&#8217;ll print out a text file with a csv MIME type, and some separated values.  The MIME type can either be &#8220;text/csv&#8221; or &#8220;text/x-csv&#8221;.  The standard, per the name, is to separated the values with a comma, and all values that contain a comma should be wrapped in double quotes.  For example:</p>
<p><code>we,are,separated</code></p>
<p><code>"And here, ",we have a, comma in a value</code></p>
<p>Another way, which may be the more common practice, per my version of OpenOffice.org, is to separate the values with a semicolon:</p>
<p><code>One;Two;Three</code></p>
<p>I&#8217;ll use the semicolon method.  Here is a quick script that will create a small CSV file, which can be read by a spreadsheet program:</p>
<pre name="code" class="php">
header("Content-type: text/csv");

$data = array(
	array(
		"a-1",
		"a-2",
		"a-3",
	),
	array(
		"b-1",
		"b-2",
		"b-3",
	),
	array(
		"c-1",
		"c-2",
		"c-3",
	),
);

foreach($data as $row) {
	echo implode(";", $row) . "\n\r";
}
</pre>
<p>Now, this will prompt the user for a download, which will end in a .php filename.  If you have access, and are using Apache, you can solve this with a little .htaccess.  Simply putting a .htaccess file in the directory, with this in it, should do the trick.</p>
<p><code>AddType application/x-httpd-php .csv</code></p>
<p>With that, working properly, you should be able to create PHP scripts that use a .csv extension.  Then, when you run the above script, save it as &#8220;mydata.csv&#8221; and the downloader should see no connection to PHP.</p>
<p>Now, how can we use this in a little more realistic scenario?  Well, we can use this to create CSV dumps of SQL result sets.</p>
<pre name="code" class="php">
$query = @mysql_query($sql);
$data = array();

while($row = @mysql_fetch_assoc($query)) {
	//first time through, grab the keys
	if(!sizeof($data)) {
		$data[] = array_keys($row);
	}	

	$tmp = array();
	foreach($row as $key=>$value) {
		$tmp[] = $value;
	}
	$data[] = $tmp;
}

foreach($data as $row) {
	echo implode(";", $row) . "\n\r";
}
</pre>
<p>And there you have it!  That script should be capable of turning your queries into a spreadsheet readable file.  Fun, right?</p>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2009/12/export-to-spreadsheet-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implementing the Singleton pattern in PHP</title>
		<link>http://seanjordan.me/2009/12/implementing-the-singleton-pattern-in-php/</link>
		<comments>http://seanjordan.me/2009/12/implementing-the-singleton-pattern-in-php/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 23:22:31 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=140</guid>
		<description><![CDATA[In short, the Singleton Pattern is a design pattern used when we want only ONE instance of a class to be initialized. This is useful in CPU/Memory intensive classes, such as database handle abstractions. The Singleton Pattern is a pretty fundamental pattern, worth learning about, if you aren&#8217;t already aware. It&#8217;s characterized by a private [...]]]></description>
			<content:encoded><![CDATA[<p>In short, the Singleton Pattern is a design pattern used when we want only ONE instance of a class to be initialized.  This is useful in CPU/Memory intensive classes, such as database handle abstractions.</p>
<p>The <a href="http://en.wikipedia.org/wiki/Singleton_pattern">Singleton Pattern</a> is a pretty fundamental pattern, worth learning about, if you aren&#8217;t already aware.  It&#8217;s characterized by a private constructor, which can only be called by class member methods, and a public static accessor method, to return a reference to the object.</p>
<p>Here is a quick example of how it can be implemented in PHP (There are other ways, as well).</p>
<pre name="code" class="php">
class Singleton {

    private static $__instance;
    protected $_value;

    private function __construct() {
        $this-&gt;_value = rand();
    }

    public static function getInstance() {
        if(!isset(self::$__instance)) {
            self::$__instance = new Singleton();
        }
        return self::$__instance;
    }

    public function display() {
        echo $this-&gt;_value . "&lt;br /&gt;";
    }

}
</pre>
<p>Use it like this:</p>
<pre name="code" class="php">
$foo = Singleton::getInstance();
$foo->display();

$bar = Singleton::getInstance();
$bar->display();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2009/12/implementing-the-singleton-pattern-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Bitwise Operators and Access Control Lists</title>
		<link>http://seanjordan.me/2009/11/php-bitwise-operators-and-access-control-lists/</link>
		<comments>http://seanjordan.me/2009/11/php-bitwise-operators-and-access-control-lists/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 02:09:55 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=94</guid>
		<description><![CDATA[Bitwise operators are a very handy tool that can be used in PHP.  The problem is they just aren&#8217;t used very often.  I really like bitwise operators, but like other PHP developers, I just don&#8217;t use them very often.  I think the cause of this is that developers just don&#8217;t realize when they COULD be [...]]]></description>
			<content:encoded><![CDATA[<p>Bitwise operators are a very handy tool that can be used in PHP.  The problem is they just aren&#8217;t used very often.  I really like bitwise operators, but like other PHP developers, I just don&#8217;t use them very often.  I think the cause of this is that developers just don&#8217;t realize when they COULD be using bitwise operators.</p>
<p>A very good example of where you should be using bitwise operators is in Access Control Lists (ACLs).  An ACL is basically a list of who has access to what.  Well, a simple way to introduce you to access control is via Unix permissions.  Most of you are probably familiar with the <span class="code">chmod</span> command.  Most of you also probably don&#8217;t have the codes memorized.  Here is a great little PHP script that will:</p>
<p><strong>A</strong>: Help you understand bitwise operators and how you might use them, and<br />
<strong>B</strong>: Help you understand and memorize the <span class="code">chmod</span> codes.</p>
<pre name="code" class="php">
define("EXECUTE", 1);
define("WRITE", 2);
define("READ", 4);

for($i = 0; $i &lt;= 7; $i++) {
$x = ($i &amp; EXECUTE) ? "x" : "-";
$w = ($i &amp; WRITE) ? "w" : "-";
$r = ($i &amp; READ) ? "r" : "-";

echo "{$i} = {$r}{$w}{$x}&lt;br /&gt;";
}
</pre>
<p>This will output:</p>
<div class="code-section">
0 = &ndash;&ndash;&ndash;<br />
1 = &ndash;&ndash;x<br />
2 = &ndash;w&ndash;<br />
3 = &ndash;wx<br />
4 = r&ndash;&ndash;<br />
5 = r&ndash;x<br />
6 = rw&ndash;<br />
7 = rwx
</div>
<p>A little note, about <span class="code">chmod</span>, just in case you were wondering now: a <span class="code">chmod</span> code is three digits.  The first digit is the access code for the file&#8217;s owner, the second digit is the access code for the group of the file&#8217;s owner, and the third digit is the access code for everyone else.  So, let&#8217;s take a code: 754.  What does this mean? Well, let&#8217;s use that list we just created to look it up.  The first digit, 7, as stated, maps to the file&#8217;s owner, so according to our list, the owner has full permissions, rwx.  Next, the second digit is a 5, and that maps to the file owner&#8217;s group; the group has r-x access: read and execute, but no write permissions.  The final digit, everyone else, is a 4: read-only access.</p>
<p>Now, how can you apply this to your code? Well, as long as you keep the integer assignments as powers of 2, you can have an infinite number of access codes:</p>
<pre name="code" class="php">
define("MAGIC", 8);

$wizard = READ | WRITE | EXECUTE | MAGIC;

if($wizard &amp; MAGIC) {
echo "Wizards can do magic &lt;br /&gt;";
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2009/11/php-bitwise-operators-and-access-control-lists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Latest reading..</title>
		<link>http://seanjordan.me/2009/11/latest-reading/</link>
		<comments>http://seanjordan.me/2009/11/latest-reading/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 08:22:16 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=71</guid>
		<description><![CDATA[Flex for PHP Developers I&#8217;m learning to work with Flex for my latest software package.  The possibility for integration with PHP makes me happy.  Ugh, I&#8217;m a nerd. I love code.  Be on the lookout for awesome applications in the future, I&#8217;m about to get dangerous.]]></description>
			<content:encoded><![CDATA[<p><a href="http://corlan.org/flex-for-php-developers/">Flex for PHP Developers</a></p>
<p>I&#8217;m learning to work with Flex for my latest software package.  The possibility for integration with PHP makes me happy.  Ugh, I&#8217;m a nerd. I love code.  Be on the lookout for awesome applications in the future, I&#8217;m about to get dangerous.</p>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2009/11/latest-reading/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>In response to my previous post&#8230;</title>
		<link>http://seanjordan.me/2009/10/in-response-to-my-previous-post/</link>
		<comments>http://seanjordan.me/2009/10/in-response-to-my-previous-post/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 07:48:04 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=43</guid>
		<description><![CDATA[My last post, Don&#8217;t store passwords as plain text! I described a simple method to create a salted hash of a password for a more secure method of storing it in a database.  If you haven&#8217;t already done so, you should read that post, to learn WHY its bad to store passwords as plain text [...]]]></description>
			<content:encoded><![CDATA[<p>My last post, <em><a href="http://seanjordan.me/2009/10/dont-store-passwords-as-plain-text/">Don&#8217;t store passwords as plain text!</a></em> I described a simple method to create a salted hash of a password for a more secure method of storing it in a database.  If you haven&#8217;t already done so, you should read that post, to learn WHY its bad to store passwords as plain text (if it isn&#8217;t obvious to you). I thought about the topic some more.  It is a very serious security issue, and so I decided that, if I&#8217;m going to make a post about the topic, I should be a little more informative.</p>
<p>I also read up a little on the topic.  It turns out that <a title="Coding Horror" href="http://www.codinghorror.com/blog/" target="_blank">Jeff Atwood</a> posted a pretty similiar <a title="Coding Horror: You're Probably Storing Passwords Incorrectly" href="http://www.codinghorror.com/blog/archives/000953.html" target="_blank">post</a> a couple years back.  Jeff made an assertion that I should make as well.  Like Jeff, I am not a cryptographer, so don&#8217;t trust my advice like I am a security EXPERT.  He also taught me about <a title="Wikipedia: Rainbow Tables" href="http://en.wikipedia.org/wiki/Rainbow_tables" target="_blank">rainbow tables</a>.  Rainbow tables, in short, are a massive database of precomputed hashes.  With our hash inside of a hash technique, the final hash product is too long for modern rainbow tables to be effective.  This is great and all, but there are a few problems with my method.  One thing you need to realize when dealing with system security is there will almost ALWAYS be security holes.  We do our best to prevent them, but we can&#8217;t promise to be 100% successful.</p>
<p>I&#8217;m going to revisit the salted hash to create a better salting, hashing, hacker-hater method of storing passwords.  I&#8217;ll make another disclaimer-like notice first.  Most people use only a handful of unique passwords (and by handful, I mean: one.. or two) across a galaxy of login systems.  If you develop a system to store a user&#8217;s password it is your responsibility to store it in the most secure way you can.  I don&#8217;t recommend you use my salty hash method, I simply mean for it to be an enlightening moment of: &#8220;Oh crap, I should really think about how I&#8217;m storing my users&#8217; passwords.&#8221;  There are always security holes.  I&#8217;ve already thought about one in my original.  I thought my method worked well, because the salt wasn&#8217;t exposed in the stored value. I liked this, but then realized a problem: two user&#8217;s with the same password will generate the same hash.  This is much the problem with storing a non-salted hash, and is the principle used in cracking hashes via brute force/rainbow table.  Hashing strings until the two generated hashes match.</p>
<p>Here is my improved method, in (PHP) code:</p>
<pre name="code" class="php">
// our password this time, is a little bit stronger than ‘password’
$password = “#aBc.123@”;

// some alpha-numeric values and special characters, for use in our salt
$salt_material = “abcdefghijklmnopqrstuvwxyz1234567890 \”!@#$%^&amp;*()_=+-{}[],./&lt;&gt;?;’:”;

// salt will be a string of random length, 1-9
$salt_length = rand(1,9);
$salt = “”;

//build the salt from our material at random choice
for($i = 0; $i &lt; $salt_length; $i++) {
$salt .= $salt_material[ rand(0, strlen($salt_material)-1) ];
}

// calculate the hashes, and then reverse the strings
// not sure about the added strength, but I like the idea of reversing the sums
$salt_sum = strrev( md5($salt) );
$password_sum = strrev( md5($password) );

// now create the sum of our salt + password
$salty_hash = md5( $salt_sum . $password_sum );

// create a hash which exposes our salt, so we know what it was.
// since our salt_length is only 1-9, this information doesn’t have to be
// separated, its always the first char
$resulting_hash = $salt_length . $salt . $salty_hash;

// for added measure, an idea I read elsewhere.
// again, not sure about the added strength, but I like the idea of it
$secure_hash = sha1($resulting_hash);

// and now, the final result
$final_product = $salt_length . $salt . $secure_hash;
</pre>
<p>Now, each time the hash is calculated, it should be a unique value, however we should be able to recreate it (provided the user inputs the correct password).  Four runs of the script resulted in the following hashes:</p>
<p>7{5@a#@@f77a51b733b65590d284b990099fc764239fbd63<br />
4n+b44c38fe32b4f9a095d7534610bce0f4d72d2976f7<br />
9r{j&amp;f2i&#8221;t9ea7035cf81de87a07980e9884d26db67e510728<br />
4;xd&#8221;a9ff52b67313cc2d183b977226747a6685540a43</p>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2009/10/in-response-to-my-previous-post/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t store passwords as plain text!</title>
		<link>http://seanjordan.me/2009/10/dont-store-passwords-as-plain-text/</link>
		<comments>http://seanjordan.me/2009/10/dont-store-passwords-as-plain-text/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 23:46:43 +0000</pubDate>
		<dc:creator>Sean Jordan</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://seanjordan.me/?p=31</guid>
		<description><![CDATA[Many websites will email your password to you if you have forgotten it.  When I create a new account on a website, I don&#8217;t want them to know my password!  They shouldn&#8217;t be storing my password somewhere as plain text.  Granted, the site could be storing a hashed version, and simply using an algorithm to [...]]]></description>
			<content:encoded><![CDATA[<p>Many websites will email your password to you if you have forgotten it.  When I create a new account on a website, I don&#8217;t want them to know my password!  They shouldn&#8217;t be storing my password somewhere as plain text.  Granted, the site could be storing a hashed version, and simply using an algorithm to unhash it, and send you back the unhashed version, but I don&#8217;t like this either.  I don&#8217;t want them to even be able to unhash my password!</p>
<p>No hashing algorithm is completely unbreakable.  Hashing algorithms such as MD5 or SHA-1 have been shown to be breakable (MD5 much more easily than SHA-1), but storing the MD5 hash of a password is still SIGNIFICANTLY more secure than storing the plain text, or an easily crackable custom hashing algorithm.  Cracking an MD5 sum can take a few minutes, several hours, or even days, depending on the CPU power available, SHA-1 even longer.</p>
<p>We can create an even more secure hash by combining the efforts of a custom hashing algorithm and MD5 to create a unique custom hashing mechanism.  This is an example of how you should store your users&#8217; passwords. We want to &#8220;salt&#8221; the original string, and then hash the salted version, and store only the hash.  When it comes time to authenticate a user&#8217;s login attempt, we run their input through the hashing function.  If the two hashes match, they&#8217;ve inserted the correct password.</p>
<p>Here is an example of such a custom salted hash:</p>
<p>Our string to be hashed is &#8220;password.&#8221; First, let&#8217;s come up with a salting mechanism.  For this example, we&#8217;ll use something simple.  The salt used has to be retrievable and positively recreatable. &#8220;Password&#8221; has 8 characters.  Lets take (in PHP)</p>
<p><code>$salt = floor(strlen("password") / 2);</code></p>
<p>That is the length of the string, divided by two, rounded down to the nearest whole number.  In our case the answer is 4.  floor() does nothing for us here, but if the string length is odd we want a whole number, and we want the same whole number every time a string of that length is used.</p>
<p>Now we have our salt, 4.  Let&#8217;s hash up the 4.</p>
<p><code>$salt_sum = md5( decbin($salt) );</code></p>
<p>I took 4, converted it to binary (results in 100), and found the MD5 sum of that as a string, the result is: f899139df5e1059396431415e770c6dd</p>
<p>Lets prepend that to our input string, &#8220;password&#8221; and find the MD5 sum:</p>
<p><code>$hash = md5($salt_sum . "password");</code></p>
<p>Now, our result is: c88e94b4d0f8e1c303f3b79d131a2d13 &#8212; and THAT is what we want to store.  Now we can recreate that, and now our MD5 sum is incredibly difficult to break, with the pre-hashed value containing a 32 character &#8220;random&#8221; string, plus the original 8.</p>
]]></content:encoded>
			<wfw:commentRss>http://seanjordan.me/2009/10/dont-store-passwords-as-plain-text/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
