Last active
December 6, 2023 01:14
-
-
Save divinity76/3eb1846fb5478120afd6e37d251a381f to your computer and use it in GitHub Desktop.
hash collisions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types = 1); | |
ini_set("memory_limit", "-1"); | |
$algo = "xxh64"; | |
$dictionary = "crackstation.txt"; | |
// MODE_dict_in_ram_hashes_in_ram($algo, $file); | |
MODE_dict_on_disk_hash_on_sqlite($algo, $dictionary); | |
function MODE_dict_on_disk_hash_on_sqlite(string $algo, string $dictionary): void | |
{ | |
$sqlite_file = __FILE__ . ".sqlite3"; | |
if (file_exists($sqlite_file)) { | |
if (! unlink($sqlite_file)) { | |
throw new \RuntimeException("unable to unlink sqlite3 file!"); | |
} | |
} | |
$db = new \PDO('sqlite:' . $sqlite_file, '', '', array( | |
\PDO::ATTR_EMULATE_PREPARES => false, | |
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, | |
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC | |
)); | |
$db->exec('PRAGMA synchronous = OFF'); | |
$db->exec('PRAGMA journal_mode = OFF'); | |
$sql = 'CREATE TABLE t ( | |
h BLOB PRIMARY KEY, | |
w BLOB NOT NULL) WITHOUT ROWID;'; | |
$db->exec($sql); | |
$fp = fopen($dictionary, "rb"); | |
$stm = $db->prepare("INSERT INTO t VALUES(?,?)"); | |
$hash = ""; | |
$word = ""; | |
$stm->bindParam(1, $hash); | |
$stm->bindParam(2, $word); | |
while (($word = fgets($fp))) { | |
$word = rtrim($word, "\n"); | |
$hash = hash($algo, $word, true); | |
try { | |
$stm->execute(); | |
} catch (\Throwable $ex) { | |
$collision = $db->query("SELECT w FROM t WHERE h = " . $db->quote($hash)) | |
->fetch(\PDO::FETCH_NUM)[0]; | |
print_collision($collision, $word); | |
} | |
//echo "."; | |
} | |
var_dump($db->query("SELECT COUNT(*) FROM t")->fetch()); | |
} | |
function MODE_dict_on_disk_hashes_in_ram(string $algo, string $dictionary): void | |
{ | |
$fp = fopen($dictionary, "rb"); | |
$hashes = []; | |
$counter = 0; | |
register_shutdown_function(function () use (&$counter) { | |
var_dump([ | |
"counter" => $counter | |
]); | |
}); | |
while (($word = fgets($fp))) { | |
++ $counter; | |
$word = rtrim($word, "\n"); | |
$hash = hash($algo, $word, true); | |
if (isset($hashes[$hash])) { | |
print_collision($hashes[$hash], $word); | |
} | |
$hashes[$hash] = $word; | |
} | |
} | |
function MODE_dict_in_ram_hashes_in_ram(string $algo, string $dictionary): void | |
{ | |
echo "loading.."; | |
$words = file($dictionary, FILE_IGNORE_NEW_LINES); | |
echo ". done!\n"; | |
$hashes = array(); | |
foreach ($words as $word) { | |
$hash = hash($algo, $word, true); | |
if (isset($hashes[$hash])) { | |
print_collision($hashes[$hash], $word); | |
} | |
$hashes[$hash] = $word; | |
} | |
} | |
function print_collision(string $str1, string $str2): void | |
{ | |
echo "\"{$str1}\" (hex " . bin2hex($str1) . " ) collides with \"{$str2}\" (hex " . bin2hex($str2) . " )\n"; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment