web-dev-qa-db-ja.com

C#:短いMD5コードを生成する方法は?

暗号化するとき23MD5暗号化を使用して37693cfc748049e45d87b8c7d8b9aacdこの32文字の長い文字列は、23の間常に静的になります。

同じ種類のメカニズムが必要ですが、生成されるメカニズムは18以下である必要があります(例:122ff1e4883358b6)32文字ではなく長い文字列。

C#でそれを行うにはどうすればよいですか?C#にMD5の短いバージョンはありますか?

21
Prashant

@RichieHindleの答えが好きです。ただし、忠実度の損失を少なくする(したがって、衝突のリスクを減らす)ことに関心がある場合は、MD5ハッシュによって返される128ビット値を取得し、 ASCII85 を使用してエンコードすることができます(これも16進数ベースのエンコーディングの代わりに、Base85エンコーディングとして知られています。これにより、ハッシュ全体が20バイトになります(これは必要以上ですが、2バイトを切り落とすことができるため、16進エンコードを使用して取得する32バイトのうち14バイトを削除するよりもはるかに少ない損失になります)。

編集:Prashantは、20文字が十分に近いと言い、サンプルコードを要求しました:

MD5.ComputeHash呼び出しからMD5ハッシュを取得した後、次を使用できます Jeff AtwoodのASCII85エンコーダー

MD5 m = MD5.Create();
byte[] hash = m.ComputeHash(System.Text.Encoding.ASCII.GetBytes("23"));
Ascii85 encoder = new Ascii85();
encoder.EnforceMarks = false;
string hash85 = encoder.Encode(hash);
Console.Out.WriteLine(hash85);

収量

2ebDPFFZsD?&,r1fX\$,

したがって、hash85を使用できます。 encoder.EnforceMarksは、ASCII85に関連付けられているいくつかの一般的なプレフィックスとサフィックスがエンコーディングに含まれていないことを確認します。

30
Blair Conrad

MD5ハッシュを必要なだけ取得し、残りを破棄することができます。すべてのビットの値が等しいため、それを行うことと、ネイティブに生成されるビット数が少ないハッシュアルゴリズムを使用することとの間に違いはありません。

(セキュリティ上の理由でこれを行う場合は、アルゴリズムに関係なく、ビット数が少ないとハッシュの解読が容易になることに注意してください。セキュリティアプリケーションの外部でも、ビット数が少ないと衝突のリスクが高まります。また、MD5はこれらの安全性が比較的低いことにも注意してください。日-SHA-1またはSHA-2はより安全であると見なされます。)

10
RichieHindle

MD5は常に128ビットハッシュを作成します。

その他の小さなハッシュタイプ(ウィキペディアから取得)

Fowler-Noll-Voハッシュ関数(32、64、128、256、512、または1024ビット)
Jenkinsハッシュ関数(32ビット)
MurmurHash(32ビットまたは64ビット)
ピアソンハッシュ(8ビット)

ただし、覚えておいてください ハッシュ衝突

7

衝突せずに結果を元の値にマップできるようにしたい場合は、ハッシュ関数を使用しません。

小さな10進数を長い難読化された文字列に変換することが目的の場合は、マッピングアルゴリズムを考案し、結果を zBase32 などでエンコードします。

public string Obfuscate(long x)
{
    return ToZBase32(BitConverter.GetBytes(x * 63498398L));
}

public long Deobfuscate(string x)
{
    return BitConverter.ToInt64(FromZBase32(x)) / 63498398L;
}

23"gmuyaiayyyyyy"にエンコードされます。 (フェアダイスロールによって選ばれた63498398。)

4
dtb

最短の有用なハッシュアルゴリズムはmd5です。 16バイト= 128ビットのハッシュを生成します。 Base 64エンコーディングを使用する場合...つまり、バイト/文字あたり6ビットです。

uはmd5を22文字(ASCII)に減らすことができるはずです。あなたが持っているのは、2バイトが1つの実際のバイトを表す16進バージョンです

(b64によって導入された末尾のパディングを残します)

正当なファイル名に同じものを使用するという追加の利点があります。 (もちろん、uはデフォルトの/および+文字を、OSのファイル命名規則と衝突しない他の記号に置き換える必要があります。

base64(/と+を置き換えることにより)は、ハッシュがURLを特殊文字で混乱させないようにします。これはWebサーバーにとって別の意味を持つ可能性があります。

ASCII85は、ファイル名やURLで使用するときに処理が難しい文字を追加します

md5( 'この文字列はハッシュされます')

'37aa3296c523f6c5a7fd2102a9155dcc'(16進数)(32バイト)

raw md5( 'この文字列はハッシュされます')

[55、170、50、150、197、35、246、197、167、253、33、2、169、21、93、204] =(16バイト)

生のmd5文字列のbase64

N6oylsUj9sWn_SECqRVdzA ==

私の最後のハッシュ

N6oylsUj9sWn_SECqRVdzAこれは実際には22のASCII文字で完全なmd5です

([末尾の2つを削除できます= md5には常に2つあります-後でデコードするときに追加します。また、b64の+文字と/文字を他の好きな文字に置き換えます-(ダッシュ)と_(アンダースコア)]

3
geekay

FVNHashを使用する- http://www.codeproject.com/KB/security/FnvHash.aspx

ハッシュの長さを設定できますセキュリティ上の理由から使用しないでください

3
dr. evil

この32文字の長い文字列は、16進数:0-fの数値です。16進数の値を36:0-zの基数に変換することで短くすることができます。

1
Anwar Chandra