Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KEINOS/3862470d353ba3f574d20d4cddf6ab8f to your computer and use it in GitHub Desktop.
Save KEINOS/3862470d353ba3f574d20d4cddf6ab8f to your computer and use it in GitHub Desktop.
hashアルゴリズムとハッシュ値の長さ一覧(+ハッシュ関数の基本と応用) ref: https://qiita.com/KEINOS/items/c92268386d265042ea16
#!/bin/bash
# RULE
VALUE_HEAD='0000'
LEN_HEAD=${#VALUE_HEAD}
# Function
function dechex() {
printf '%x' $1
}
function isValidNonce() {
[ "${1:0:$LEN_HEAD}" = "${VALUE_HEAD}" ]
return $?
}
function hash() {
algo=$1
value=$2
echo $(echo -n $value | openssl $algo | awk '{print $2}')
}
# Data
data='something'
hash='34902903de8d4fee8e6afe868982f0dd'
nonce=''
# Mining/Search nonce
counter=0
while true
do
nonce=$(dechex $counter)
string_to_hash="${data}${hash}${nonce}"
hash_temp=$(hash 'md5' $string_to_hash)
isValidNonce $hash_temp && {
break
}
counter=$((counter+1))
done
echo "Nonce found: ${nonce}"
// 値が異なる $a と $b
$a = 'xx..1..xx'
$b = 'xx..0..xx'
hash('md5', $a) === hash('md5', $b) // true, 偶然にも衝突が発生!
hash('md2', $a) === hash('md2', $b) // false, アルゴリズムが異なると衝突しない(可能性が高い)
$key_prime_new = hash('fnv164', $key_prime_old);
CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z);
<?php
/* Nonce のルール */
// 最初の4文字が 0 である
$head_value = '0000';
$head_len = strlen($head_value);
/* 前のブロック */
$data_previous = 'sample1';
$hash_previous = 'a4626f9d3e6802aebbff46697248e0b9';
$nonce_previous = 'xxxxxx';
/* 現在のブロック */
$data_current = 'sample2';
$hash_current = hash('md5', $data_previous . $hash_previous . $nonce_previous);
$nonce_current = '';
// Nonce 探索
$i = 0;
while( true ){
$nonce_current = dechex($i);
$hash_temp = hash('md5', $data_current . $hash_current . $nonce_current);
// $hash_temp の頭 n 文字をルールと比較( n = $head_len )
if(substr($hash_temp, 0, $head_len) === $head_value){
echo 'Nonce found: ' . $nonce_current . PHP_EOL;
echo PHP_EOL;
break;
};
$i++;
}
/* Nonce の検証。Verify Nonce の頭が n 桁が 0 であることを確認 */
echo 'Block Data:' . PHP_EOL;
echo 'Data: ' . $data_current . PHP_EOL;
echo 'Hash: ' . $hash_current . PHP_EOL;
echo 'Nonce: ' . $nonce_current . PHP_EOL;
echo 'Verify Nonce: ' . hash('md5', $data_current . $hash_current . $nonce_current) . PHP_EOL;
$key_prime_new = hash('fnv164', $key_prime_old);
// 旧IDでデータ取得
$value = fetchValueFromDB($key_prime_old);
// データ → ハッシュ化(16進)→ 10進 → 整数
$key_prime_new = (integer) hexdec(hash('fnv164', $value));
$key_prime_hex = hash('fnv132', $value) . hash('crc32', $value);
$key_prime_new = hash('fnv164', $key_prime_old);
#!/bin/bash
name_db='sample.db'
# Create table 1 and 2 and insert same data
sqlite3 $name_db <<'HEREDOC'
create table table1(myID INT not null primary key, myName Varchar);
insert into table1 values(100, "First value with ID 100");
insert into table1 values(10, "Second value with ID 10 ");
insert into table1 values(1, "Third value with ID 1 ");
create table table2(myID integer not null primary key, myName Varchar);
insert into table2 values(100, "First value with ID 100");
insert into table2 values(10, "Second value with ID 10 ");
insert into table2 values(1, "Third value with ID 1 ");
HEREDOC
echo '- DB created with sample.'
// 旧IDでデータ取得
$value = fetchValueFromDB($key_prime_old);
// データ → ハッシュ化(16進)→ 10進 → 整数
$key_prime_new = (integer) hexdec(hash('fnv164', $value));
#!/bin/bash
name_db='sample.db'
# Create table 1 and 2 and insert same data
sqlite3 $name_db <<'HEREDOC'
create table table1(myID INT not null primary key, myName Varchar);
insert into table1 values(100, "First value with ID 100");
insert into table1 values(10, "Second value with ID 10 ");
insert into table1 values(1, "Third value with ID 1 ");
create table table2(myID integer not null primary key, myName Varchar);
insert into table2 values(100, "First value with ID 100");
insert into table2 values(10, "Second value with ID 10 ");
insert into table2 values(1, "Third value with ID 1 ");
HEREDOC
echo '- DB created with sample.'
$key_prime_hex = hash('fnv132', $value) . hash('crc32', $value);
#!/bin/bash
name_db='sample.db'
# Create table 1 and 2 and insert same data
sqlite3 $name_db <<'HEREDOC'
create table table1(myID INT not null primary key, myName Varchar);
insert into table1 values(100, "First value with ID 100");
insert into table1 values(10, "Second value with ID 10 ");
insert into table1 values(1, "Third value with ID 1 ");
create table table2(myID INTEGER not null primary key, myName Varchar);
insert into table2 values(100, "First value with ID 100");
insert into table2 values(10, "Second value with ID 10 ");
insert into table2 values(1, "Third value with ID 1 ");
HEREDOC
echo '- DB created with sample.'
$key_prime_new = hash('fnv164', $key_prime_old);
$key_prime_new = hash('fnv164', $key_prime_old);
$key_prime_new = hash('fnv164', $key_prime_old);
$key_prime_new = hash('fnv164', $key_prime_old);
$key_prime_new = hash('fnv164', $key_prime_old);
// 旧IDでデータ取得
$value = fetchValueFromDB($key_prime_old);
// データ → ハッシュ化(16進)→ 10進 → 整数
$key_prime_new = (integer) hexdec(hash('fnv164', $value));
$key_prime_hex = hash('fnv132', $value) . hash('crc32', $value);
$key_prime_new = hash('fnv164', $key_prime_old);
$passwd_hashed = md5($passwd . $salt . $pepper);
$key_prime_new = hash('fnv164', $key_prime_old);
$key_prime_new = hash('fnv164', $key_prime_old);
[
{
"hash": "<hash1>",
"data": "<data1>",
"nonce": "<nonce1>"
},
{
"hash": "<hash2>",
"data": "<data2>",
"nonce": "<nonce2>"
},
...
]
// 旧IDでデータ取得
$value = fetchValueFromDB($key_prime_old);
// データ → ハッシュ化(16進)→ 10進 → 整数
$key_prime_new = (integer) hexdec(hash('fnv164', $value));
[
{
"hash": "<hash1>",
"data": "<data1>",
"nonce": "<nonce1>"
},
{
"hash": "<hash2>",
"data": "<data2>",
"nonce": "<nonce2>"
},
...
]
$key_prime_new = hash('fnv164', $key_prime_old);
$key_prime_new = hash('fnv164', $key_prime_old);
[
{
"hash": "<hash1>",
"data": "<data1>",
"nonce": "<nonce1>"
},
{
"hash": "<hash2>",
"data": "<data2>",
"nonce": "<nonce2>"
},
...
]
// 最初の4文字が 0 である
define('VALUE_HEAD', '0000');
define('LEN_HEAD', strlen(VALUE_HEAD));
/* 検証用の関数 */
function isValidNonce(string $nonce): bool
{
// ルール:$nonce の頭 n 文字が VALUE_HEAD と同じ( n = LEN_HEAD )
return (substr($nonce, 0, LEN_HEAD) === VALUE_HEAD);
}
function isValidHashInLatestBlock(array $block_chain): bool
{
// 現在のブロックの長さ
$len_block_chain = count($block_chain);
// 2つ前のブロックのデータ取得
$key_2block_ago = $len_block_chain - 2;
$data_2block_ago = $block_chain[$key_2block_ago]['data'];
$hash_2block_ago = $block_chain[$key_2block_ago]['hash'];
$nonce_2block_ago = $block_chain[$key_2block_ago]['nonce'];
// 期待するハッシュ値の算出
$hash_previous_expect = hash('md5', $data_2block_ago. $hash_2block_ago . $nonce_2block_ago);
// 1つ前のブロックのハッシュ値取得
$key_block_previous = $len_block_chain - 1;
$hash_previous_actual = $block_chain[$key_block_previous]['hash'];
// 1つ目のブロックのハッシュ値の検証
return ($hash_previous_expect === $hash_previous_actual);
}
function getBlockLatest(array $block_chain):array
{
$len_block_chain = count($block_chain)-1;
return $block_chain[$len_block_chain];
}
CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z);
# .header on と .mode column は見栄えを整える SQLite3 コマンドです
echo '- Table1'
sqlite3 $name_db <<'HEREDOC'
.header on
.mode column
select rowid, * from table1;
HEREDOC
echo '- Table2'
sqlite3 $name_db <<'HEREDOC'
.header on
.mode column
select rowid, * from table2;
HEREDOC
$ # 絹ごし牛ミンチ
$ echo -n 'beef' | openssl sha512
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$ # 絹ごし牛ミンチ(コマンドの言語が違っても同じアルゴリズムと引数なら同じミンチ肉)
$ php -r 'echo hash("sha512", "beef"), PHP_EOL;'
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$ # 絹ごし牛ミンチ+ 1g の塩入り
$ salt=1; echo -n 'beef'$salt | openssl sha512
a528829f370819123ad3fb04d8066b77ec79ce6eddad07e5b2c925bbd9b2e699e73428d23315875c29b45500b8c767262cf5546e33974e4f7a6102abd1bb045e
$ # 絹ごし牛ミンチ+ 1g の塩入り(コックが違っても同じレシピなら同じ味)
$ php -r '$salt=1; echo hash("sha512", "beef" . $salt), PHP_EOL;'
a528829f370819123ad3fb04d8066b77ec79ce6eddad07e5b2c925bbd9b2e699e73428d23315875c29b45500b8c767262cf5546e33974e4f7a6102abd1bb045e
$ # 絹ごし牛ミンチ
$ php -r 'echo hash("sha512", "beef"), PHP_EOL;'
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$ # 絹ごし牛ミンチ(コマンドの言語が違っても同じアルゴリズムと引数なら同じミンチ肉)
$ echo -n 'beef' | openssl sha512
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$ # 絹ごし牛ミンチ+ 1g の塩入り
$ php -r '$salt=1; echo hash("sha512", "beef" . $salt), PHP_EOL;'
a528829f370819123ad3fb04d8066b77ec79ce6eddad07e5b2c925bbd9b2e699e73428d23315875c29b45500b8c767262cf5546e33974e4f7a6102abd1bb045e
$ # 絹ごし牛ミンチ+ 1g の塩入り(コックが違っても同じレシピなら同じ味)
$ salt=1; echo -n 'beef'$salt | openssl sha512
a528829f370819123ad3fb04d8066b77ec79ce6eddad07e5b2c925bbd9b2e699e73428d23315875c29b45500b8c767262cf5546e33974e4f7a6102abd1bb045e
$len = 8; //4バイトのHEX文字列長
$value = fetchValueFromDB($key_prime_old);
$hash1 = substr(hash('sha256', $value), 0, $len);
$hash2 = substr(hash('sha512', $value), 0, $len);
// 8バイトの主キー
$key_prine_new = (integer) hexdec($hash1 . $hash2);
$ # 粗挽き牛ミンチ
$ php -r 'echo hash("md5", "beef"), PHP_EOL;'
34902903de8d4fee8e6afe868982f0dd
$
$ # 粗挽き牛ミンチ(二度目でも同じミンチ肉)
$ php -r 'echo hash("md5", "beef"), PHP_EOL;'
34902903de8d4fee8e6afe868982f0dd
$
$ # 粗挽き牛ミンチ+ 1g の塩入り
$ php -r 'echo hash("md5", "beef" . "salt 1g"), PHP_EOL;'
cf06d6a163ee0ca858d008767654e893
$
$ # 絹ごし牛ミンチ
$ php -r 'echo hash("sha512", "beef"), PHP_EOL;'
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$
$ # 絹ごし牛ミンチ(二度目でも同じミンチ肉)
$ php -r 'echo hash("sha512", "beef"), PHP_EOL;'
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$
$ # 絹ごし牛ミンチ+ 1g の塩入り
$ php -r 'echo hash("sha512", "beef" . "salt 1g"), PHP_EOL;'
6b545481ac7d8e61267745ed39f2a135d5eeff65cdb992f34794f87f843ab8bedd29bbd07ff9444b3005f1d3fcb36ce213f54b63481708eeb691f71f5afe155a
/* 1つ前のブロックの検証 */
if(! isValidHashInLatestBlock($block_chain)){
echo 'Error: Not a valid hash value. Block-chain broken.' . PHP_EOL;
exit(1);
}
/* 新規ブロックのデータ作成 */
// 追加したいデータ
$data_current = 'sample3';
// ブロックのハッシュ値を計算(1つ前のブロックより)
$block_previous = getBlockLatest($block_chain);
$hash_current = hash('md5', $block_previous['data'] . $block_previous['hash'] . $block_previous['nonce']);
$block_current = [
'data' => $data_current,
'hash' => $hash_current,
];
echo 'Request to add to the block-chain.' . PHP_EOL;
echo ' Data:' . $data_current . PHP_EOL;
echo ' Hash:' . $hash_current . PHP_EOL;
/* 1つ前のブロックの検証 */
if(! isValidHashInLatestBlock($block_chain)){
echo 'Error: Not a valid hash value. Block-chain broken.' . PHP_EOL;
exit(1);
}
$hash_verify = hash('md5', $data_current . $hash_current . $nonce_current);
echo 'Hash result: ' . $hash_verify . PHP_EOL;
if(! isValidNonce($hash_verify)){
echo ' Error: Nonce not valid.' . PHP_EOL;
exit(1);
};
// ブロック・チェーンに追加
$block_chain[] = [
'data' => $data_current,
'hash' => $hash_current,
'nonce' => $nonce_current,
];
echo ' Success: New data added to block-chain.' . PHP_EOL;
// ブロック・チェーンの内容表示
echo 'Current Block-Chain:' . PHP_EOL;
print_r($block_chain);
$list_url_visited=[
'http://hoge.com/p1',
'http://hoge.com/p6',
'http://hoge.com/p4',
...
];
asort($list_url_visited); //配列をソート
$string = implode(' ', $list_url_visited); //配列を文字列に結合
$id_visited = hash('md5', $string); //文字列をハッシュ化
/* 1つ前のブロックの検証 */
if(! isValidHashInLatestBlock($block_chain)){
echo 'Error: Not a valid hash value. Block-chain broken.' . PHP_EOL;
exit(1);
}
$data_current = $block_current['data'];
$hash_current = $block_current['hash'];
$nonce_current = '';
// Nonce 探索
$i = 0;
while( true ){
$nonce_current = dechex($i);
$hash_temp = hash('md5', $data_current . $hash_current . $nonce_current);
if(isValidNonce($hash_temp)){
echo 'Nonce found: ' . $hash_temp . PHP_EOL;
break;
}
$i++;
}
/* マイニングの結果(これを検証依頼する) */
echo 'Block Data to add:' . PHP_EOL;
echo ' Data: ' . $data_current . PHP_EOL;
echo ' Hash: ' . $hash_current . PHP_EOL;
echo ' Nonce: ' . $nonce_current . PHP_EOL;
$ # ハッシュド・ポテト
$ echo -n 'poteto' | openssl md5
147f31c730caa77f8a3440e549264a2e
$ # トマト・ペースト
$ echo -n 'tomato' | openssl md5
006f87892f47ef9aa60fa5ed01a440fb
- Table2
myID myID myName
---------- ---------- ------------------------
1 1 Third value with ID 1
10 10 Second value with ID 10
100 100 First value with ID 100
- Table1
rowid myID myName
---------- ---------- ------------------------
1 100 First value with ID 100
2 10 Second value with ID 10
3 1 Third value with ID 1
$ php -a
Interactive shell
php > $url_pdf1='https://shattered.io/static/shattered-1.pdf';
php > $url_pdf2='https://shattered.io/static/shattered-2.pdf';
php > $algo = 'sha1'; //衝突する
php > echo hash($algo, file_get_contents($url_pdf1)), PHP_EOL;
38762cf7f55934b34d179ae6a4c80cadccbb7f0a
php > echo hash($algo, file_get_contents($url_pdf2)), PHP_EOL;
38762cf7f55934b34d179ae6a4c80cadccbb7f0a
php > $algo = 'md5'; //衝突しない
php > echo hash($algo, file_get_contents($url_pdf1)), PHP_EOL;
ee4aa52b139d925f8d8884402b0a750c
php > echo hash($algo, file_get_contents($url_pdf2)), PHP_EOL;
5bd9d8cabc46041579a311230539b8d1
php > exit
$ # 粗挽き牛ミンチ
$ php -r 'echo hash("md5", "beef"), PHP_EOL;'
34902903de8d4fee8e6afe868982f0dd
$ # 粗挽き牛ミンチ(コマンドの言語が違っても同じアルゴリズムと引数なら同じミンチ肉)
$ echo -n 'beef' | openssl md5
34902903de8d4fee8e6afe868982f0dd
$ # 絹ごし牛ミンチ
$ php -r 'echo hash("sha512", "beef"), PHP_EOL;'
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$
$ # 絹ごし牛ミンチ(二度目でも同じミンチ肉)
$ php -r 'echo hash("sha512", "beef"), PHP_EOL;'
8cd8bb0cef938ef9cd054c2c2cb965e83310ab5c197cb5fc8f35892a44c1a028bac9e1bcd6248580fa2739cc96074885ea3ee116ef35c2d8f6124270aeff50b7
$
$ # 絹ごし牛ミンチ+ 1g の塩入り
$ php -r '$salt=1; echo hash("sha512", "beef" . $salt), PHP_EOL;'
a528829f370819123ad3fb04d8066b77ec79ce6eddad07e5b2c925bbd9b2e699e73428d23315875c29b45500b8c767262cf5546e33974e4f7a6102abd1bb045e
$ # 粗挽き牛ミンチ
$ echo -n 'beef' | openssl md5
34902903de8d4fee8e6afe868982f0dd
$ # 粗挽き牛ミンチ(言語が違っても同じアルゴリズムと引数なら同じミンチ肉)
$ php -r 'echo hash("md5", "beef"), PHP_EOL;'
34902903de8d4fee8e6afe868982f0dd
$ # 粗挽き牛ミンチ+ 1 の塩入り
$ php -r '$salt=1; echo hash("md5", "beef" . $salt), PHP_EOL;'
30017279d6a5bac241e764eeed261dd8
$ # 同じレシピで、違う言語のコマンド(bash)
$ salt=1; echo -n 'beef'$salt | openssl md5
30017279d6a5bac241e764eeed261dd8
$ # 粗挽き牛ミンチ + 1g の塩入り
$ salt=1; echo -n 'beef'$salt | openssl md5
30017279d6a5bac241e764eeed261dd8
$ # 粗挽き牛ミンチ + 1g の塩入り(コックが違っても同じレシピなら同じ味)
$ php -r '$salt=1; echo hash("md5", "beef" . $salt), PHP_EOL;'
30017279d6a5bac241e764eeed261dd8
// 2つ前のブロック・データ
$block_chain[] = [
'data' => 'sample1',
'hash' => 'a4626f9d3e6802aebbff46697248e0b9',
'nonce' => 'xxxxxx',
];
// 1つ前のブロック・データ(Latest)
$block_chain[] = [
'data' => 'sample2',
'hash' => '3152851bf5419247cf948e871b0adfe8',
'nonce' => '32648',
];
<?php
$url_pdf1='https://shattered.io/static/shattered-1.pdf';
$url_pdf2='https://shattered.io/static/shattered-2.pdf';
$algo = 'sha1'; //衝突する
echo hash($algo, file_get_contents($url_pdf1)), PHP_EOL;
echo hash($algo, file_get_contents($url_pdf2)), PHP_EOL;
$algo = 'md5'; //衝突しない
echo hash($algo, file_get_contents($url_pdf1)), PHP_EOL;
echo hash($algo, file_get_contents($url_pdf2)), PHP_EOL;
exit
<?php
// MD5 で衝突するサンプルデータ
$str1 = '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518'
. 'afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2';
// ↑ ↑
$str2 = '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518'
. 'afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2';
// ↑ ↑
// バイナリに変換
$bin1 = hex2bin(trim($str1));
$bin2 = hex2bin(trim($str2));
// 衝突させる
$algo = 'md5';
$md5_a = hash($algo, $bin1);
$md5_b = hash($algo, $bin2);
echo ( $md5_a === $md5_b ) ? '衝突しました' : '衝突していません', PHP_EOL;
// 別のアルゴリズムで確認
$algo = 'sha1';
$sha1_a = hash($algo, $bin1);
$sha1_b = hash($algo, $bin2);
echo ( $sha1_a === $sha1_b ) ? '衝突しました' : '衝突していません', PHP_EOL;
/* 出力結果 */
// 衝突しました
// 衝突していません
// 値が微妙に異なる $a と $b
$a = 'xxxxxxxxx..1..xxxxxxxxx'; // 長ったらしい値 a
$b = 'xxxxxxxxx..0..xxxxxxxxx'; // 長ったらしい値 b
$result_sha1 = (hash('sha1', $a) === hash('sha1', $b));
$result_md5 = (hash('md5', $a) === hash('md5', $b));
// $result_sha1 -> true, 偶然にも衝突が発生!
// $result_md5 -> false, アルゴリズムが異なると衝突しない(可能性が高い)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment