先日、Twitterでこんなツイートを見かけた。
社内Slackで突如はじまった、Checksum Sum Battle。
ルールは明快。ユーザ名のmd5値の総和が多いほうが勝ち🙌🏻
プレイヤーになるもよし、アルゴリズムの良さを競うもありで、ちょっとした気分転換にw
// もっといいワンライナを書いてくれるエンジニア募集(?)→https://t.co/5fjbSBxFYN pic.twitter.com/VNWZ0kKZd1
— suin (@suin) March 13, 2018
おお、なんか面白そう。 大文字や小文字、改行コードのある無しでもhashは異なってくるので、そのあたりのパターン分けも含めたら、どれかは結構な大きさの総和になるかもしれない。 という訳でやってみた。
bcを使って計算する場合
bcでは16進数での計算ができるのだけど、その際「a~f」は大文字で記述してあげる必要がある。 なので、bcに渡す前にhashのアルファベットをすべてupper(大文字)変換してやればいい。
echo blacknon|md5sum|sed -r 's/[ -]//g;s/./\U&/g;s/\B/+/g;s/^/obase=10;ibase=16;/'|bc
printf blacknon|md5sum|sed -r 's/[ -]//g;s/./\U&/g;s/\B/+/g;s/^/obase=10;ibase=16;/'|bc # 改行を含めない場合
blacknon@BS-PUB-UBUNTU-01:~$ echo blacknon|md5sum|sed -r 's/[ -]//g;s/./\U&/g;s/\B/+/g;s/^/obase=10;ibase=16;/'|bc
276
blacknon@BS-PUB-UBUNTU-01:~$ printf blacknon|md5sum|sed -r 's/[ -]//g;s/./\U&/g;s/\B/+/g;s/^/obase=10;ibase=16;/'|bc # 改行を含めない場合
290
bashの算術展開を使って計算する場合
bashの算術展開では、0xを頭に付けることで16進数での計算が行える。
echo blacknon|md5sum|sed 's/[a-f0-9]/0x&+/g;s/[ -]//g'|echo $(($(cat)+0))
printf blacknon|md5sum|sed 's/[a-f0-9]/0x&+/g;s/[ -]//g'|echo $(($(cat)+0)) # 改行を含めない場合
blacknon@BS-PUB-UBUNTU-01:~$ echo blacknon|md5sum|sed 's/[a-f0-9]/0x&+/g;s/[ -]//g'|echo $(($(cat)+0))
276
blacknon@BS-PUB-UBUNTU-01:~$ printf blacknon|md5sum|sed 's/[a-f0-9]/0x&+/g;s/[ -]//g'|echo $(($(cat)+0)) # 改行を含めない場合
290
大文字・小文字の組み合わせで総和の大きいものを調べる
せっかくなので、大文字・小文字の全組み合わせで総和の大きいものを調べてみる。 総和を求める箇所についてはperlで行っている。
echo blacknon|sed 's/./{\U&,\L&}/g'|eval echo $(cat)|fmt -1|xargs -I@ -n1 bash -c "printf @:;echo @|md5sum|perl -lne 's/[ -]//g;s/\B/+/g;s/([a-f])/0x\1/g;print eval $_'"|sort -t: -k2nr|head
echo blacknon|sed 's/./{\U&,\L&}/g'|eval echo $(cat)|fmt -1|xargs -I@ -n1 bash -c "printf @:;printf @|md5sum|perl -lne 's/[ -]//g;s/\B/+/g;s/([a-f])/0x\1/g;print eval $_'"|sort -t: -k2nr|head # 改行を含めない場合
blacknon@BS-PUB-UBUNTU-01:~$ echo blacknon|sed 's/./{\U&,\L&}/g'|eval echo $(cat)|fmt -1|xargs -I@ -n1 bash -c "printf @:;echo @|md5sum|perl -lne 's/[ -]//g;s/\B/+/g;s/([a-f])/0x\1/g;print eval $_'"|sort -t: -k2nr|head
BlAcKnON:310
bLAcKnoN:310
blACkNOn:296
BLACkNon:292
blAckNon:289
blacKNon:289
BLacknON:288
blACKNON:288
bLacKnON:283
BLACKnOn:282
blacknon@BS-PUB-UBUNTU-01:~$ echo blacknon|sed 's/./{\U&,\L&}/g'|eval echo $(cat)|fmt -1|xargs -I@ -n1 bash -c "printf @:;printf @|md5sum|perl -lne 's/[ -]//g;s/\B/+/g;s/([a-f])/0x\1/g;print eval $_'"|sort -t: -k2nr|head # 改行を含めない場合
blACKNON:305
bLAcKnon:304
BlAcKnON:303
BlacKNoN:303
BLacKnoN:292
BlAcknON:292
BlAcKNOn:291
BlacknoN:290
blACKnOn:290
blacknon:290
まぁ、ただ"ハッシュから大きい数字を得る"だけなら、md5じゃなくてsha512にしてしまえばまさに 桁違いの数字
を得られるのだけど、ドラゴンボールとか小学生の遊びみたいにインフレしていくことになるからそれは無しの方向で(´・ω・`)。
ちなみにsha512にすれば1,000点台も夢じゃない。
blacknon@BS-PUB-UBUNTU-01:~$ echo blacknon|sha512sum|perl -lne 's/[ -]//g;s/\B/+/g;s/([a-f])/0x\1/g;print eval $_'
1062