我是一个Go语言初学者,目前遇到了麻烦。 我想要将一个字符串使用UTF16小端编码,然后使用MD5(十六进制)进行哈希。我已经找到了一段Python代码,可以完美地实现我的需求。但我无法将其转换为Google Go。
md5 = hashlib.md5()
md5.update(challenge.encode('utf-16le'))
response = md5.hexdigest()
挑战是一个包含字符串的变量。
func utf16leMd5(s string) []byte {
enc := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
hasher := md5.New()
t := transform.NewWriter(hasher, enc)
t.Write([]byte(s))
return hasher.Sum(nil)
}
unicode/utf16
包进行 UTF-16 编码。 utf16.Encode()
返回 Unicode 代码点序列(符文切片:[]rune
)的 UTF-16 编码。您只需将 string
转换为符文切片,例如 []rune("some string")
,并通过遍历 uint16
代码并首先发送/附加低位字节然后是高位字节以输出轻松生成小端编码的字节序列(这就是 Little Endian 的含义)。encoding/binary
包:它具有导出的 LittleEndian
变量和一个 PutUint16()
方法。crypto/md5
包具有您想要的功能,md5.Sum()
简单地返回传递给它的字节切片的 MD5 校验和。func utf16leMd5(s string) [16]byte {
codes := utf16.Encode([]rune(s))
b := make([]byte, len(codes)*2)
for i, r := range codes {
b[i*2] = byte(r)
b[i*2+1] = byte(r >> 8)
}
return md5.Sum(b)
}
使用它:
s := "Hello, playground"
fmt.Printf("%x\n", utf16leMd5(s))
s = "エヌガミ"
fmt.Printf("%x\n", utf16leMd5(s))
输出:
8f4a54c6ac7b88936e990256cc9d335b
5f0db9e9859fd27f750eb1a212ad6212
在Go Playground上试试。
使用encoding/binary
的变体如下所示:
for i, r := range codes {
binary.LittleEndian.PutUint16(b[i*2:], r)
}
因此,供参考,我使用了这个完整的Python程序:
import hashlib
import codecs
md5 = hashlib.md5()
md5.update(codecs.encode('Hello, playground', 'utf-16le'))
response = md5.hexdigest()
print response
它会打印出 8f4a54c6ac7b88936e990256cc9d335b
这里是 Go 语言的等效代码:https://play.golang.org/p/Nbzz1dCSGI
package main
import (
"crypto/md5"
"encoding/binary"
"encoding/hex"
"fmt"
"unicode/utf16"
)
func main() {
s := "Hello, playground"
fmt.Println(md5Utf16le(s))
}
func md5Utf16le(s string) string {
encoded := utf16.Encode([]rune(s))
b := convertUTF16ToLittleEndianBytes(encoded)
return md5Hexadecimal(b)
}
func md5Hexadecimal(b []byte) string {
h := md5.New()
h.Write(b)
return hex.EncodeToString(h.Sum(nil))
}
func convertUTF16ToLittleEndianBytes(u []uint16) []byte {
b := make([]byte, 2*len(u))
for index, value := range u {
binary.LittleEndian.PutUint16(b[index*2:], value)
}
return b
}