簡體   English   中英

C# 和 Kotlin(Java) 中的 MD5 哈希碼

[英]MD5 Hashcode in C# and Kotlin(Java)

我正在努力解決 Kotlin (Java) 和 C# 中 MD5 結果消耗的差異。 我發現這篇文章建議了解決方案:

如何在 C# 和 Java 中生成相同的 MD5 哈希碼?

但我想了解這背后的邏輯。 我做了幾個測試。 C#:

var data = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("123456"));
var s = Encoding.UTF8.GetString(data, 0, data.Length);

產生以下字節序列(數據變量):

 225, 10, 220, 57, 73, 186, 89, 171, 190, 86, 224, 87, 242, 15, 136, 62

如果我使用 Kotlin (Java):

val md = MessageDigest.getInstance("MD5")
val data = md.digest("123456".toByteArray())

val s = String(data)

val ls2 = data.map { x-> x.toUByte() }

所以 Java 有帶符號的字節,而 c# 無符號(ls2 - 包含與 c# 示例相同的無符號字節)。 美好的。 我想獲得字符串值 - 我將兩個字節 arrays 轉換為字符串,我得到了不同的字符串(s 變量)。 我想念什么?

謝謝。

在 C# 中,您嘗試使用 UTF-8 編碼將字節轉換為字符串。 然而,這是一個非常糟糕的主意——在 UTF-8 編碼的字符串中有許多無效的字節序列,還有更多的序列會導致無法打印的字符。 如果編碼器遇到不形成有效 UTF-8 編碼字符的字節序列(它會這樣做,因為您沒有做任何事情來確保您的字節序列是有效的 UTF-8 編碼字符串),它將插入一個替換字符。

在 Kotlin 中,您使用使用系統編碼的new String(byte[]) 您在這里遇到了類似的問題:盡管大多數字節都會產生有效字符,但其中一些字符將無法打印。

因此,您對 C# 和 Kotlin 使用了兩種不同的編碼(因此結果不同),但您也在做一些可能會給您無法打印的字符,或者可能用替換字符替換字節序列(因此不同的 MD5 哈希看起來相同)。

(請注意,“不可打印的字符”可能只是不可見,但它們可能會做一些奇怪的事情,例如反轉該頁面上的文本方向,或者開始將它們周圍的字符連接在一起!)

最好將字節轉換為 base64 字符串或十六進制字符序列。 這兩者都確保每個可能的字節序列都以在不同語言之間保持一致的方式轉換為可打印字符。

對於 C#,使用Convert.ToBase64String(data)獲取 base64 編碼的字符串,使用BitConverter.ToString(data).Replace("-","")獲取十六進制編碼的字符串(雖然有很多方法可以做這個)。

對於 Kotlin,使用Base64.getEncoder().encodeToString(data)獲取 base64 編碼字符串, data.joinToString("") { "%02x".format(it) }獲取十六進制編碼字符串。

暫無
暫無

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

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