なでしこさんでハッシュ値の最初何文字かに0が連続する文字列を探す
今週も安定の頭の悪さを発揮し、書きたいことを書くための作業ができず。
雑プログラムで繋ぐことを決定するも、雑プログラムもなかなか思いつかず。
実装を開始した時点で残り約1時間、記事を書き始めた時点で残り約25分。
……なんでここまで無理して週streakを繋ごうとするんだろう……?
今回やったこと
なでしこで、指定した文字列から始まり、ハッシュ値 (SHA-256 / SHA-384 / SHA-512) の最初の指定した文字数が全て 0 であるような文字列を探す。
プログラム
ハッシュ値の最初何文字かに0が連続する文字列を探す (プログラム貯蔵庫)
解説
前回の記事と違って、今回は複数パートあるよ!
UIの用意
接頭辞エディタは空のエディタ作成。
「から始まって、」のラベル作成。
改行作成。
アルゴリズム選択は["SHA-256", "SHA-384", "SHA-512"]のセレクトボックス作成。
「を十六進数で表したとき、最初の」のラベル作成。
改行作成。
個数エディタは「4」のエディタ作成。
それの「type」に「number」をDOM属性設定。
それの「min」に「0」をDOM属性設定。
「文字が0であるような文字列を」のラベル作成。
改行作成。
探すボタンは「探す!」のボタン作成。
2回、改行作成。
「見つけた文字列:」のラベル作成。
結果文字列欄は空のラベル作成。
改行作成。
「そのハッシュ値:」のラベル作成。
結果ハッシュ値欄は空のラベル作成。各種命令を用いて、何を探索するかを入力する部分、探索を実行するボタン、結果を表示する部分を作る。
探索を行う関数の用意
●(PREFIXでALGのNUMを)探すとは
定数のターゲットは「0」をNUMでリフレイン。
変数の番号は0。
永遠に繰り返す
定数のデータは「{PREFIX}{番号}」。
定数のハッシュ値はデータをALGでハッシュ値計算。
もし、ハッシュ値がターゲットで文字始まるならば
{
"文字列": データ,
"ハッシュ値": ハッシュ値,
}を戻す。
ここまで。
番号を1増やす。
ここまで。
ここまで。実際に探索を行う関数を用意する。
この関数は、以下の引数をとる。
PREFIX:探す文字列の最初の部分
ALG:ハッシュ値のアルゴリズムを表す文字列 (「ハッシュ値計算」が対応しているもの)
NUM:ハッシュ値の最初何文字が0である文字列を探すか
探す方法は、指定の接尾辞に十進数を0から順番にくっつけてそのハッシュ値を求める、という操作をハッシュ値が条件を満たすまで繰り返す、という愚直な方法である。
見つけたら、見つけた文字列とそのハッシュ値の十六進数表現を格納したオブジェクトを返す。
探すボタンの処理
探すボタンがクリックされたら、以下の処理を行う。(以下の処理はイベントハンドラの中身である)
定数の接頭辞は接頭辞エディタのテキスト取得。
アルゴリズム選択のテキスト取得して小文字変換。
定数のアルゴリズムはそれ。
個数エディタのテキスト取得して整数変換。
定数の個数はそれ。
もし、(個数をNAN判定)または(個数が0未満)ならば
「個数がおかしいよ!」と言う。
空を戻す。
ここまで。UIの部品から条件を取得する。
ハッシュ値を求めるアルゴリズムの名前は、「ハッシュ値計算」で用いるのは小文字であるが、一般的だと思うのは大文字なので、UIには大文字で載せておき、「小文字変換」で「ハッシュ値計算」用のアルゴリズム名に変換する。
もし、個数が6以上ならば
「警告!{改行}6文字以上連続した0の探索は、ものすごく長時間かかる可能性が高いです。{改行}それでも実行しますか?」の二択。
もし、それがいいえならば
空を戻す。
ここまで。
ここまで。
もし、個数が5ならば
「5文字以上連続した0の探索は、長時間(数分とか)かかる可能性があります。{改行}実行しますか?」の二択。
もし、それがいいえならば
空を戻す。
ここまで。
ここまで。探索に長時間かかりそうな大きい個数が指定された場合、警告し、キャンセルの機会を与える。
あくまで長時間かかる「可能性が高い」だけであり、接頭辞によっては「0」を追加したものが条件を満たしてすぐに探索が終わることもあるだろう。
結果文字列欄に空をテキスト設定。
結果ハッシュ値欄に「探しています…」をテキスト設定。
接頭辞エディタにオフをDOM有効設定。
アルゴリズム選択にオフをDOM有効設定。
個数エディタにオフをDOM有効設定。
探すボタンにオフをDOM有効設定。
0秒待つ。探索中、前回の探索結果を消し、UIを無効化する。
それが反映されやすいよう、内部で Promise を用いる「秒待」で実行を区切る。
定数の開始時刻はシステム時間ミリ秒。
定数の結果は接頭辞でアルゴリズムの個数を探す。
定数の終了時刻はシステム時間ミリ秒。
結果文字列欄に結果$文字列をテキスト設定。
結果ハッシュ値欄に結果$ハッシュ値をテキスト設定。
0秒待つ。
「{(終了時刻-開始時刻)÷1000}秒で見つかりました!」と言う。
接頭辞エディタにオンをDOM有効設定。
アルゴリズム選択にオンをDOM有効設定。
個数エディタにオンをDOM有効設定。
探すボタンにオンをDOM有効設定。時刻を用いて時間を測りながら探索を行い、結果をUIに設定する。
再び「秒待」で実行を区切り、かかった時間を言う (alert ダイアログで表示する)。
その後、UIを有効化する。
おわりに
今回のプログラムは、本当に実用性が無い。
テスト用などでハッシュ値の先頭何文字かが連続して 0 になるデータが欲しいときでも、もっと高速に探索できるプログラムを用いるべきだ。


コメント