私はAndroidにWindowsアプリケーションを移植しており、エンディアンに関する問題が発生しています。このアプリケーションはユーザーから一連のテキストフィールドを受け取り、MD5に基づいてパスワードを生成します。問題は、MD5ダイジェストメソッドに渡すためにバイト配列を作成するときです。Androidアプリのバイトはビッグエンディアン形式です。したがって、MD5出力は2つのプラットフォーム間で一致しません。AndroidリトルエンディアンMD5
ByteBufferを使用してリトルエンディアンに変換し、その値をByteBuffer.get()を使用してバイト配列にコピーしてみました。悲しいことに、それは注文設定を維持していないので動作しません。これは、ByteBuffersを扱う際に知られている "つかの間"のようです。 ByteBuffer.getLong()の値とWindows版の同等の値を比較すると、値は一致しますが、正しい順序でByteBufferから配列を戻す方法はわかりません。
編集:私は以下のjava関数とC#関数の両方を添付しました。
以下順/エンディアンを修正しようとしないJavaのバージョンです:
public static final long md5(final String input) {
try {
// Create MD5
MessageDigest md5 = MessageDigest.getInstance("MD5");
// Read in string as an array of bytes.
byte[] originalBytes = input.getBytes("US-ASCII");
byte[] encodedBytes = md5.digest(originalBytes);
long output = 0;
long multiplier = 1;
// Create 64 bit integer from the MD5 hash of the input
for (int i = 0; i < encodedBytes.length; i++) {
output = output + encodedBytes[i] * multiplier;
multiplier = multiplier * 255;
}
return output;
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return 0;
}
そしてここでは、C#バージョン
private Int64 MD5(string input)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] originalBytes = ASCIIEncoding.ASCII.GetBytes(input);
byte[] encodedBytes = md5.ComputeHash(originalBytes);
Int64 output = 0;
Int64 Multiplyer = 1;
for (int i = 0; i < encodedBytes.Length; i++)
{
output = output + encodedBytes[i] * Multiplyer;
Multiplyer = Multiplyer * 255;
}
return output;
}
私はあなたが問題について混乱していると思う - テキストからバイナリへの変換とMD5アルゴリズムの両方で単純なバイト配列が生成されます。 –
しかし、ダイジェストメソッドに入るバイトの順序は関係ありませんか? – quesauce
はい、そうです。 Windows版に入った最初のバイトは、アンドロイドに入る最初のバイトでなければなりません。しかし、エンディアンは、バイトストリームではなく、ワード内のバイトの順序に関係します。 –