<?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>Hash function &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/hash-function/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Rabin-Karp String Searching</title>
		<link>/2012/04/02/computer-algorithms-rabin-karp-string-searching/</link>
		<comments>/2012/04/02/computer-algorithms-rabin-karp-string-searching/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 19:48:15 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[ASCII]]></category>
		<category><![CDATA[basic sub-string matching algorithm]]></category>
		<category><![CDATA[Boyer–Moore string search algorithm]]></category>
		<category><![CDATA[Complexity The Rabin-Karp algorithm]]></category>
		<category><![CDATA[Cryptographic hash function]]></category>
		<category><![CDATA[Cryptography]]></category>
		<category><![CDATA[Hash function]]></category>
		<category><![CDATA[Hash table]]></category>
		<category><![CDATA[Hashing]]></category>
		<category><![CDATA[Michael O. Rabin]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Rabin-Karp algorithm]]></category>
		<category><![CDATA[Rabin-Karp string search algorithm]]></category>
		<category><![CDATA[Richard M. Karp]]></category>
		<category><![CDATA[Rolling hash]]></category>
		<category><![CDATA[search algorithms]]></category>
		<category><![CDATA[string matching algorithms]]></category>
		<category><![CDATA[String searching algorithm]]></category>
		<category><![CDATA[string searching algorithms]]></category>
		<category><![CDATA[sub-string matching algorithms]]></category>
		<category><![CDATA[This algorithm]]></category>

		<guid isPermaLink="false">/?p=2991</guid>
		<description><![CDATA[Introduction Brute force string matching is the a very basic sub-string matching algorithm, but it’s good for some reasons. For example it doesn’t require preprocessing of the text or the pattern. The problem is that it’s very slow. That is why in many cases brute force matching can’t be very useful. For pattern matching we &#8230; <a href="/2012/04/02/computer-algorithms-rabin-karp-string-searching/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Rabin-Karp String Searching</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/04/09/computer-algorithms-morris-pratt-string-searching/" rel="bookmark" title="Computer Algorithms: Morris-Pratt String Searching">Computer Algorithms: Morris-Pratt String Searching </a></li>
<li><a href="/2012/04/17/computer-algorithms-boyer-moore-string-search-and-matching/" rel="bookmark" title="Computer Algorithms: Boyer-Moore String Searching">Computer Algorithms: Boyer-Moore String Searching </a></li>
<li><a href="/2012/03/27/computer-algorithms-brute-force-string-matching/" rel="bookmark" title="Computer Algorithms: Brute Force String Matching">Computer Algorithms: Brute Force String Matching </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a href="/2012/03/27/computer-algorithms-brute-force-string-matching/" title="Computer Algorithms: Brute Force String Searching">Brute force string matching</a> is the a very basic sub-string matching algorithm, but it’s good for some reasons. For example it doesn’t require preprocessing of the text or the pattern. The problem is that it’s very slow. That is why in many cases brute force matching can’t be very useful. For pattern matching we need something faster, but to understand other sub-string matching algorithms let’s take a look once again on brute force matching. </p>
<p>In brute force sub-string matching we checked every single character from the text with the first character of the pattern. Once we have a match between them we shift the comparison between the second character of the pattern with the next character of the text, as shown on the picture below.</p>
<p><figure id="attachment_3002" style="width: 618px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Rabin-Karp-Brute-Froce-Principles.png"><img src="/wp-content/uploads/2012/04/Rabin-Karp-Brute-Froce-Principles.png" alt="Brute Froce Principles" title="Brute Froce Principles" width="618" height="242" class="size-full wp-image-3002" srcset="/wp-content/uploads/2012/04/Rabin-Karp-Brute-Froce-Principles.png 618w, /wp-content/uploads/2012/04/Rabin-Karp-Brute-Froce-Principles-300x117.png 300w" sizes="(max-width: 618px) 100vw, 618px" /></a><figcaption class="wp-caption-text">Brute force string matching is slow because it compares every single character from the pattern and the text!</figcaption></figure><span id="more-2991"></span></p>
<p>This algorithm is slow for mainly two reasons. First we have to check every single character from the text. On the other hand even if we find a match between a text character and the first character of the pattern we continue to check step by step (character by character) every single symbol of the pattern in order to find whether it is in the text. So is there any other approach to find whether the text contains the pattern?</p>
<p>In fact there is a “faster” approach. In this case in order to avoid the comparison between the pattern and the text character by character, we’ll try to compare them at once, so we need a good hash function. With its help we can hash the pattern and check against hashed sub-strings of the text. We must be sure that the hash function is returning “small” hash codes for larger sub-strings. Another problem is that for larger patterns we can’t expect to have short hashes. But besides this the approach should be quite effective compared to the brute force string matching. </p>
<p>That approach is known as Rabin-Karp algorithm.</p>
<h2>Overview</h2>
<p><a href="http://en.wikipedia.org/wiki/Michael_O._Rabin" title="Michael O. Rabin" target="_blank">Michael O. Rabin</a> and <a href="http://en.wikipedia.org/wiki/Richard_M._Karp" title="Richard M. Karp" target="_blank">Richard M. Karp</a> came up with the idea of hashing the pattern and to check it against a hashed sub-string from the text in 1987. In general the idea seems quite simple, the only thing is that we need a hash function that gives different hashes for different sub-strings. Such hash function, for instance, may use the ASCII codes for every character, but we must be careful for multi-lingual support.</p>
<figure id="attachment_3003" style="width: 621px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Rabin-Karp-Basic-Principles.png"><img src="/wp-content/uploads/2012/04/Rabin-Karp-Basic-Principles.png" alt="Rabin-Karp Basic Principles" title="Rabin-Karp Basic Principles" width="621" height="299" class="size-full wp-image-3003" srcset="/wp-content/uploads/2012/04/Rabin-Karp-Basic-Principles.png 621w, /wp-content/uploads/2012/04/Rabin-Karp-Basic-Principles-300x144.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></a><figcaption class="wp-caption-text">Rabin-Karp hashes the pattern and the sub-string in order to compare them quickly!</figcaption></figure>
<p>The hash function may vary depending on many things, so it may consist of ASCII char to number converting, but it can be also anything else. The only thing we need is to convert a string (pattern) into some hash that is faster to compare. Let’s say we have the string “hello world”, and let’s assume that its hash is hash(‘hello world’) = 12345. So if hash(‘he’) = 1 we can say that the pattern “he” is contained in the text “hello world”. Thus on every step we take from the text a sub-string with the length of m, where m is the pattern length. Thus we hash this sub-string and we can directly compare it to the hashed pattern, as on the picture above.</p>
<h2>Implementation</h2>
<p>So far we saw some diagrams explaining the Rabin-Karp algorithm, but let’s take a look on its implementation. Here in this very basic example where a simple hash table is used in order to convert the characters into integers. The code is PHP and it&#8217;s used only to illustrate the principles of this algorithm.</p>
<pre lang="PHP">
function hash_string($str, $len)
{
	$hash = '';
 
	$hash_table = array(
		'h' => 1,
		'e' => 2,
		'l' => 3,
		'o' => 4,
		'w' => 5,
		'r' => 6,
		'd' => 7,
	);
 
	for ($i = 0; $i < $len; $i++) {
		$hash .= $hash_table[$str{$i}];
	}
 
	return (int)$hash;
}
 
function rabin_karp($text, $pattern)
{
	$n = strlen($text);
	$m = strlen($pattern);
 
	$text_hash = hash_string(substr($text, 0, $m), $m);
	$pattern_hash = hash_string($pattern, $m);
 
	for ($i = 0; $i < $n-$m+1; $i++) {
		if ($text_hash == $pattern_hash) {
			return $i;
		}
 
		$text_hash = hash_string(substr($text, $i, $m), $m);
	}
 
	return -1;
}
 
// 2
echo rabin_karp('hello world', 'ello');
</pre>
<h3>Multiple Pattern Match</h3>
<p>It’s great to say that the Rabin-Karp algorithm is great for multiple pattern match. Indeed its nature is supposed to support such functionality, which is its advantage in compare to other string searching algorithms.</p>
<h2>Complexity</h2>
<p>The Rabin-Karp algorithm has the complexity of O(nm) where <strong>n</strong>, of course, is the length of the text, while <strong>m</strong> is the length of the pattern. So where it is compared to brute-force matching? Well, brute force matching complexity is O(nm), so as it seems there’s no much gain in performance. However it’s considered that Rabin-Karp’s complexity is O(n+m) in practice, and that makes it a bit faster, as shown on the chart below.</p>
<figure id="attachment_3001" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Rabin-Karp-Complexity.png"><img src="/wp-content/uploads/2012/04/Rabin-Karp-Complexity.png" alt="Rabin-Karp Complexity" title="Rabin-Karp Complexity" width="600" height="371" class="size-full wp-image-3001" srcset="/wp-content/uploads/2012/04/Rabin-Karp-Complexity.png 600w, /wp-content/uploads/2012/04/Rabin-Karp-Complexity-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">Rabin-Karp&#039;s complexity is O(nm), but in practice it&#039;s O(n+m)!</figcaption></figure>
<p>Note that the Rabin-Karp algorithm also needs O(m) preprocessing time.</p>
<h2>Application</h2>
<p>As we saw Rabin-Karp is not so faster than brute force matching. So where we should use it?</p>
<h3>3 Reasons Why Rabin-Karp is Cool</h3>
<p>1. Good for plagiarism, because it can deal with multiple pattern matching!<br />
<figure id="attachment_3000" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Application-of-Rabin-Karp.png"><img src="/wp-content/uploads/2012/04/Application-of-Rabin-Karp.png" alt="Application of Rabin-Karp" title="Application of Rabin-Karp" width="620" height="399" class="size-full wp-image-3000" srcset="/wp-content/uploads/2012/04/Application-of-Rabin-Karp.png 620w, /wp-content/uploads/2012/04/Application-of-Rabin-Karp-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Rabin-Karp can detect plagiarism efficiently!</figcaption></figure></p>
<p>2. Not faster than brute force matching in theory, but in practice its complexity is O(n+m)!<br />
3. With a good hashing function it can be quite effective and it's easy to implement!</p>
<h3>2 Reasons Why Rabin-Karp is Not Cool</h3>
<p>1. There are lots of string matching algorithms that are faster than O(n+m)<br />
2. It’s practically as slow as brute force matching and it requires additional space</p>
<h2>Final Words</h2>
<p>Rabin-Karp is a great algorithm for one simple reason - it can be used to match against multiple pattern. This makes it perfect to detect plagiarism even for larger phrases. </p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/04/09/computer-algorithms-morris-pratt-string-searching/" rel="bookmark" title="Computer Algorithms: Morris-Pratt String Searching">Computer Algorithms: Morris-Pratt String Searching </a></li>
<li><a href="/2012/04/17/computer-algorithms-boyer-moore-string-search-and-matching/" rel="bookmark" title="Computer Algorithms: Boyer-Moore String Searching">Computer Algorithms: Boyer-Moore String Searching </a></li>
<li><a href="/2012/03/27/computer-algorithms-brute-force-string-matching/" rel="bookmark" title="Computer Algorithms: Brute Force String Matching">Computer Algorithms: Brute Force String Matching </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/04/02/computer-algorithms-rabin-karp-string-searching/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Secure Forms with Zend Framework</title>
		<link>/2010/04/09/secure-forms-with-zend-framework/</link>
		<comments>/2010/04/09/secure-forms-with-zend-framework/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 07:16:17 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[Computer programming]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Cryptographic hash function]]></category>
		<category><![CDATA[Hash function]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[MD5]]></category>
		<category><![CDATA[PHP programming language]]></category>
		<category><![CDATA[possible solution]]></category>
		<category><![CDATA[Session]]></category>
		<category><![CDATA[web server]]></category>

		<guid isPermaLink="false">/?p=1421</guid>
		<description><![CDATA[Maybe the correct title is not &#8220;with Zend Framework&#8221;, but &#8220;with PHP&#8221;, because the general approach I used is purely PHP and no Zend Framework dependency is used. However let me mention that ZF allows you to build forms with Zend_Form, which gives you an abstraction over the HTML forms with many goodies like validation, &#8230; <a href="/2010/04/09/secure-forms-with-zend-framework/" class="more-link">Continue reading <span class="screen-reader-text">Secure Forms with Zend Framework</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2010/06/10/json-and-zend-framework-zend_json/" rel="bookmark" title="JSON and Zend Framework? &#8211; Zend_Json">JSON and Zend Framework? &#8211; Zend_Json </a></li>
<li><a href="/2010/04/28/zend_datesetoptions-and-format_type-in-zend-framework-1-10-3/" rel="bookmark" title="Zend_Date::setOptions and format_type in Zend Framework 1.10.3">Zend_Date::setOptions and format_type in Zend Framework 1.10.3 </a></li>
<li><a href="/2010/07/19/zend-framework-cache-database-table-schemes/" rel="bookmark" title="Zend Framework: Cache Database Table Schemes">Zend Framework: Cache Database Table Schemes </a></li>
<li><a href="/2010/07/21/setting-up-global-cache-in-zend-framework/" rel="bookmark" title="Setting Up Global Cache in Zend Framework">Setting Up Global Cache in Zend Framework </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<p>Maybe the correct title is not &#8220;with Zend Framework&#8221;, but &#8220;with PHP&#8221;, because the general approach I used is purely PHP and no <a title="Zend Framework" href="http://framework.zend.com/" target="_blank">Zend Framework</a> dependency is used. However let me mention that ZF allows you to build forms with Zend_Form, which gives you an abstraction over the HTML forms with many goodies like validation, filtering and protection.</p>
<h2>Zend_Form and Zend_Form_Element_Hash</h2>
<p>Although the technique I&#8217;m using is doing the same thing, note that in ZF there&#8217;s a <a title="Zend_Form_Element_Hash" href="http://framework.zend.com/apidoc/core/Zend_Form/Element/Zend_Form_Element_Hash.html" target="_blank">Zend_Form_Element_Hash</a> which generates and validates the form, thus protecting you from CSRF attacks. The thing is that I didn&#8217;t use it because the form I&#8217;m protecting is not generated with <a title="Zend_Form" href="http://framework.zend.com/manual/en/zend.form.html" target="_blank">Zend_Form</a>, and I cannot benefit from everything ZF is giving to me. However you can easily reproduce the basic strategy with every form and every framework till it&#8217;s written in PHP.</p>
<h2>What&#8217;s the solution?</h2>
<p>It&#8217;s pretty simple and it&#8217;s described many many times around the web, simply generate a random hash, a possible solution is to use uniqid in combination with mt_rand and md5, thus you&#8217;d get quite strong hash.</p>
<p>Step two is to pass this generated hash, also stored in the session in a hidden value of the form. Of course now the most asked question is: but that&#8217;s visible to the source and thus everybody will have a valid hash.</p>
<p>There&#8217;s the trick. OK everybody will have a valid hash, but on submit the hash is validated against the SESSION variable, and as you know the session is specified between the browser (client) and the web server. Although the attacker may have a valid hash he must execute the attacking script from the same domain, possibly with the same browser, which makes the task rather difficult.</p>
<h2>An Example</h2>
<p>Let me show a breve example, it may help make things clearer.</p>
<p>1. First step &#8211; start the session</p>
<pre lang="php" escaped="true">
&lt;?php
session_start();
?&gt;
</pre>
<p>2. Second step &#8211; validate the form against the $_SESSION and generate a valid token</p>
<pre lang="php" escaped="true">
&lt;?php
if (isset($_POST['name']) &amp;&amp; $_POST['token'] == $_SESSION['token'])
    echo $_POST['name'];
else
    echo 'dont hack';

$_SESSION['token'] = md5(uniqid('test', true));
?&gt;
</pre>
<p>3. Third step &#8211; make a form</p>
<pre lang="html4strict" escaped="true">
&lt;form method="POST" action=""&gt;
&lt;input type="hidden" value="&lt;?php echo $_SESSION['token'] ?&gt;" name="token" /&gt;
&lt;input type="text" name="name" value="stoimen" /&gt;
&lt;input type="submit" name="submit" /&gt;
&lt;/form&gt;
</pre>
<p><a href="http://www.stoimen.com/projects/php.secure.forms/">Demo here</a>.</p>
<p>For more to test this you may try to make the same form somewhere else on the web and to point the action to http://www.stoimen.com/projects/php.secure.forms/! Without the session validation it&#8217;s absolutely sure you can post on the attacked server. </p>
<p>P.S. Now I&#8217;ve to admit that this have nothing to do with Zend Framework, however it&#8217;s good practice and thus may be used with every framework.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2010/06/10/json-and-zend-framework-zend_json/" rel="bookmark" title="JSON and Zend Framework? &#8211; Zend_Json">JSON and Zend Framework? &#8211; Zend_Json </a></li>
<li><a href="/2010/04/28/zend_datesetoptions-and-format_type-in-zend-framework-1-10-3/" rel="bookmark" title="Zend_Date::setOptions and format_type in Zend Framework 1.10.3">Zend_Date::setOptions and format_type in Zend Framework 1.10.3 </a></li>
<li><a href="/2010/07/19/zend-framework-cache-database-table-schemes/" rel="bookmark" title="Zend Framework: Cache Database Table Schemes">Zend Framework: Cache Database Table Schemes </a></li>
<li><a href="/2010/07/21/setting-up-global-cache-in-zend-framework/" rel="bookmark" title="Setting Up Global Cache in Zend Framework">Setting Up Global Cache in Zend Framework </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2010/04/09/secure-forms-with-zend-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
