簡體   English   中英

Android小端MD5

[英]Android little endian MD5

我正在將一個Windows應用程序移植到Android上,我遇到了一個帶有字節序的問題。 該應用程序從用戶處獲取一系列文本字段,並根據MD5生成密碼。 問題是當我創建字節數組以傳遞到MD5摘要方法時,Android應用程序上的字節采用大端格式。 因此,MD5輸出在兩個平台之間不匹配。

我嘗試使用ByteBuffer轉換為little endian,然后使用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;
}

問題是這行Java:

            output = output + encodedBytes[i] * multiplier;

與這一系列的C#代碼略有不同:

    output = output + encodedBytes[i] * Multiplyer;

具體來說, encodedBytes[i]bytelong (Java)或Int64 (C#)的隱式轉換有點不同。

你看,在Java中,一個byte之間是有符號-128127 ,而在C#中,它之間的無符號0255 因此,例如,如果encodedBytes[i]B21011 0010 ),則Java將其解釋為-78,而C#將其解釋為178。

要在Java中模擬C#解釋,您可以編寫如下內容:

            output = output + ((encodedBytes[i] + 256) % 256) * multiplier;

(幸運的是,Java對整數溢出的處理與C#的“未經檢查”模式相同,這顯然就是你正在使用的模式;如果你不得不這樣做, 將會更難以模仿。)

MD5標准要求128位值,而不是64位。 首先,簽名private Int64 MD5(string input)毫無意義。 您不應該將這些轉換為整數並嘗試比較它們。 只需傳遞byte[]引用並比較它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM