]> git.mxchange.org Git - core.git/blobdiff - contrib/chash/chash.php
Moved for merge preparation.
[core.git] / contrib / chash / chash.php
diff --git a/contrib/chash/chash.php b/contrib/chash/chash.php
new file mode 100644 (file)
index 0000000..a1e91c2
--- /dev/null
@@ -0,0 +1,197 @@
+<?php
+error_reporting(E_ALL | E_STRICT);
+
+/**
+ * Continued-hashing
+ *
+ * @author             Roland Haeder <roland@mxchange.org>
+ * @copyright  Copyright (c) 2013 by Core Developer Team
+ * @license            See LICENSE (public-domain)
+ */
+
+/**
+ * Calculates a simple but stronger hash from given string. No salts are being
+ * added here.
+ *
+ * @param      $str    The string to be hashed
+ * @return     $hash   The hash from string $str
+ */
+function hashString ($str) {
+       // Calculate strong hash from given string
+       $hash = mhash(MHASH_RIPEMD320, $str);
+
+       // Return it hexadecimal-encoded
+       return bin2hex($hash);
+}
+
+/**
+ * Double-hashes given string. This is done by hashing the given string and
+ * then hashing the generated hash again.
+ *
+ * @param      $str    The string to be hashed 4 times
+ * @return     $hash   The generated hash
+ */
+function doubleHashString ($str) {
+       // Generate hash from given hash
+       $hash = hashString(hashString($str));
+
+       // Return it
+       return $hash;
+}
+
+/**
+ * Calculates a "modula-hash" based given two hashes.
+ *
+ * @param      $hash1  Hash 1
+ * @param      $hash2  Hash 2
+ */
+function modulaHash ($hash1, $hash2) {
+       // Both must have same length
+       assert(strlen($hash1) === strlen($hash2));
+
+       // Init new hash
+       $modulaHash = '';
+
+       // "Walk" trough first hash and get every 2 byte of both hashes
+       for ($idx = 0; $idx < strlen($hash1); $idx += 2) {
+               // Init modula value
+               $mod = 0;
+
+               // Get both hash parts and convert to ASCII number
+               $part1 = hexdec(substr($hash1, $idx, 2));
+               $part2 = hexdec(substr($hash2, $idx, 2));
+
+               /*
+                * If part1 is larget part2, part1 is divident and vise-versa. But don't do it
+                * if one is zero
+                */
+               if (($part1 > $part2) && ($part2 > 0)) {
+                       // 'part1' is larger than 'part2'
+                       $mod = $part1 % $part2;
+               } elseif (($part1 < $part2) && ($part1 > 0)) {
+                       // 'part2' is larger than 'part1'
+                       $mod = $part2 % $part1;
+               }
+
+               // "Invert" the result against 255
+               $mod = 255 - $mod;
+
+               // Encode to hex, pre-pad it with zeros and add to new hash
+               $modulaHash .= padHex($mod);
+       } // END - for
+
+       // Modula hash must have same length as input hash
+       assert(strlen($modulaHash) === strlen($hash1));
+
+       // Return modula hash
+       return $modulaHash;
+}
+
+/**
+ * Calculates a "sqrt-hash" based given two hashes and single-hash it
+ *
+ * @param      $hash1  Hash 1
+ * @param      $hash2  Hash 2
+ */
+function sqrtHash ($hash1, $hash2) {
+       // Both must have same length
+       assert(strlen($hash1) === strlen($hash2));
+
+       // Init new hash
+       $sqrtHash = '';
+
+       // "Walk" trough first hash and get every 2 byte of both hashes
+       for ($idx = 0; $idx < strlen($hash1); $idx += 2) {
+               // Init modula value
+               $mod = 0;
+
+               // Get both hash parts and convert to ASCII number
+               $part1 = hexdec(substr($hash1, $idx, 2));
+               $part2 = hexdec(substr($hash2, $idx, 2));
+
+               // Calculate square root of both parts being multiplied and round up, then "invert" it against 255
+               $sqrt = intval(255 - ceil(sqrt($part1 * $part2)));
+
+               // Encode to hex, pre-pad it with zeros and add to new hash
+               $sqrtHash .= padHex($sqrt);
+       } // END - for
+
+       // "sqrt-hash" must have same length as input hash
+       assert(strlen($sqrtHash) === strlen($hash1));
+
+       // Hash reversed "sqrt-hash" again and return it
+       return hashString(strrev($sqrtHash));
+}
+
+/**
+ * Converts a number between 0 and 255 into a zero-padded hexadecimal string
+ *
+ * @param      $num    Number between 0 and 255
+ * @return     $hex    Hexadecimal string, padded with zeros
+ */
+function padHex ($num) {
+       // Must be a integer number and between 0 and 255
+       assert(is_int($num));
+       assert($num >= 0);
+       assert($num <= 255);
+
+       // Convert it
+       $hex = str_pad(dechex($num), 2, '0', STR_PAD_LEFT);
+
+       // ... and return it
+       return $hex;
+}
+
+/*
+ * Calculate "genesis" hashes, please note that these "genesis strings" are now
+ * known to the public as you can read them here in source code and therefore I
+ * will not use them for the real genesis hashes.
+ */
+$hashes = array(
+       // A famous quote from Deus Ex 2 - Invisible War
+       doublehashString('"Informations must be free." - AI Helios'),
+       // My name + URL of my first StatusNet instance
+       doubleHashString('Roland Haeder, http://status.mxchange.org'),
+       // A famous quote from Linus Torwalds
+       doubleHashString('"Software is like sex. Its better when its free." - Linus Torwalds'),
+       // Possible truth ;-)
+       doubleHashString('September 11 is a big lie.'),
+
+       // GNU is not Uni*
+       doubleHashString('GNU is Not Uni*.'),
+       // WINE is not an emulator
+       doubleHashString('WINE Is Not an Emulator.'),
+       // FlightGear - Fly free!
+       doubleHashString('FlightGear - Fly free!'),
+       // Linus Torwalds Quote
+       doubleHashString('Your code is shit.. your argument is shit.'),
+);
+
+// Calculate "modula hash" from 1st/4th and 2nd/3rd
+$modulaHashes = array(
+       // "Block" 0
+       modulaHash($hashes[0], $hashes[3]),
+       modulaHash($hashes[1], $hashes[2]),
+
+       // "Block" 1
+       modulaHash($hashes[4], $hashes[7]),
+       modulaHash($hashes[5], $hashes[6]),
+);
+
+// Calculate "sqrt hash"
+$sqrtHashes = array(
+       sqrtHash($modulaHashes[0], $modulaHashes[1]),
+       sqrtHash($modulaHashes[2], $modulaHashes[3])
+);
+
+// Calulcate modula hash
+$modulaHash = modulaHash($sqrtHashes[0], $sqrtHashes[1]);
+
+// Output results
+print ('hashes=' . print_r($hashes, TRUE));
+print ('modulaHashes=' . print_r($modulaHashes, TRUE));
+print ('sqrtHashes=' . print_r($sqrtHashes, TRUE));
+print ('modulaHash=' . $modulaHash . PHP_EOL);
+
+// [EOF]
+?>