В 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) }
, чтобы получить шестнадцатеричную строку.