web-dev-qa-db-ja.com

SHA1に一致する正規表現

汎用テキストのSHA1を正規表現と一致させようとしています。

理想的には、単語の一致を避けたいです。

完全なSHA1には独特のパターン(長くて一貫した長さ)があると言っても安全です。したがって、これらを確実に一致させることができます。ただし、省略されたSHA1はどうですか?

数字の存在に依存できますか?

私のコミットログのSHA1を見ると、番号は常に最初の3文字で表示されます。しかし、これは短すぎますか?数字が表示されると想定する前に、SHA1の文字をいくつ検討する必要がありますか?

これは100%正確である必要はありません-短縮されたSHA1を99%一致させる必要があるだけです。

35
git-noob

SHA1ハッシュは完全にランダムであると考えることができるので、これは確率の問題に減少します。特定の数字が数値ではない確率は6/16、つまり0.375です。 SHA1の3桁がすべて数字ではない確率は、0.375 ** 3、つまり0.0527(5%ish)です。 6桁で、これは0.00278(0.2%)に再び減少します。 5桁では、すべての文字の確率が1%未満に低下します(99%の確率で一致したいと言っていました)。

常にSHA1値に一致する正規表現を作成するのは簡単です。

\b[0-9a-f]{5,40}\b

ただし、これは「追加」や「色あせた」など、完全に適切な5文字の単語と一致する場合もあります。私の/usr/share/dict/wordsファイル、一致する6文字の単語がいくつかあります。「accede」、「beaded」、「bedded」、「decade」、「deface」、「efface」、「facade」が最も可能性が高いです。 7文字の場合、散文に現れる可能性が低い「証書」のみがあります。それはすべて、許容できる誤検知の数、および実際に遭遇する可能性のある単語が何であるかに依存します。

67
Greg Hewgill

正確に何をしようとしていますか?ヒューリスティックスを使用してgit出力を解析する必要はありません。必要なデータを常に正確に要求できます。

SHA1サムの完全な16進表現と一致させたい場合は、以下を試してください。

/\b([a-f0-9]{40})\b/

つまり、数字または文字a〜fのいずれかである40文字で構成されるワード。

数文字しかなく、それらがどこにあるのかわからない場合は、ほとんど運がありません。 「e78fd98」は短縮されたコミットIDですか?多分、でも「1234567」はどうですか?これはコミットIDですか?問題のチケット番号?テストを失敗させる数?

コンテキストがなければ、データの意味を実際に知ることはできません。

あなたの直接の質問に答えるために、最初の3文字(16進形式)を数字にするSHA1の特性はありません。あなたはそれをどのように見るかによって、あなたはただ運がいい、またはおそらく運が悪い。

35
jrockway

16進数で表示されたSHA1の印刷表現と照合し、同等の20生バイトと照合したくないと仮定します。さらに、問題のSHA1は16進数を表すために小文字だけを使用すると想定します。要件が異なる場合は、正規表現を調整する必要があります。

grep -o -E -e "[0-9a-f]{40}"

そんなSHA1にマッチします。上記の正規表現をegrepの方言から、使用しているツールに変換する必要があります。一致は正確に40文字でなければならないので、誤って単語を一致させる危険はないと思います。 aからfの文字だけで構成される40文字の単語は知りません。

編集:

さらに良い方法は、 SHA1に一致する正規表現 を使用することです。彼のソリューションには、両端のWord境界のチェックが含まれているためです。上記を見落としました。

5
bendin

リポジトリにアクセスできる場合は、git cat-file -eを使用して、リポジトリ内のオブジェクトを表していることを確認できます。これも非常に高速です。これをコミットとタグだけに制限したい場合は、git cat-file -tを使用してオブジェクトのタイプを調べることができます。

これは、たとえば、人間が生成したテキストでgitコミットの言及を検索し、git Webインターフェースへのハイパーリンクを生成するために使用できます。

3
Neil Mayhew

このタイプのハッシュの場合:43:A4:02:B7:B6:1D:89:86:C5:CE:AD:52:96:D9:2E:7B:64:98:45:6A

/^[0-9A-F]{2}(:[0-9A-F]{2}){19}$/
0
Dededede4

Rubyで使用します。これは、shaの短いバージョン(衝突の場合は6-8)と、40文字の完全なshaを可能にします。

\A(([0-9a-f]{40})|([0-9a-f]{6,8}))\z
0
JeffCharter