Golang编码字符串UTF16 little endian和hash with MD5

phi*_*ips 4 hash md5 go

我是一名Go初学者并且遇到了问题.我想用UTF16小端编码一个字符串,然后用MD5(十六进制)散列它.我找到了一段Python代码,它完全符合我的要求.但我无法将其转移到Google Go.

md5 = hashlib.md5()
md5.update(challenge.encode('utf-16le'))
response = md5.hexdigest()
Run Code Online (Sandbox Code Playgroud)

挑战是包含字符串的变量.

hob*_*bbs 7

您可以使用golang.org/x/text/encodinggolang.org/x/text/transform创建一个可以进行编码和散列的Writer链,从而减少工作量(或至少更易理解,IMO)这么多手动字节切片处理.等效功能:

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)
}
Run Code Online (Sandbox Code Playgroud)


icz*_*cza 5

您可以使用该unicode/utf16包进行 UTF-16 编码。utf16.Encode()返回 Unicode 代码点序列的 UTF-16 编码(符文片段:)[]rune。您可以简单地将 a 转换string为符文切片,例如[]rune("some string"),并且您可以通过范围遍历来轻松生成小端编码的字节序列uint16并首先发送/附加低字节然后是高字节到输出来轻松生成小端编码的字节序列(这是Little Endian 的含义)。

\n

对于 Little Endian 编码,您也可以使用该encoding/binary包:它有一个导出的LittleEndian变量并且有一个PutUint16()方法。

\n

至于MD5校验和,crypto/md5包里有你想要的,md5.Sum()只是返回传递给它的字节片的MD5校验和。

\n

这是一个捕获您想要执行的操作的小函数:

\n
func utf16leMd5(s string) [16]byte {\n    codes := utf16.Encode([]rune(s))\n    b := make([]byte, len(codes)*2)\n    for i, r := range codes {\n        b[i*2] = byte(r)\n        b[i*2+1] = byte(r >> 8)\n    }\n    return md5.Sum(b)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

使用它:

\n
s := "Hello, playground"\nfmt.Printf("%x\\n", utf16leMd5(s))\n\ns = "\xe3\x82\xa8\xe3\x83\x8c\xe3\x82\xac\xe3\x83\x9f"\nfmt.Printf("%x\\n", utf16leMd5(s))\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
8f4a54c6ac7b88936e990256cc9d335b\n5f0db9e9859fd27f750eb1a212ad6212\n
Run Code Online (Sandbox Code Playgroud)\n

在Go Playground上尝试一下。

\n

使用的变体encoding/binary如下所示:

\n
for i, r := range codes {\n    binary.LittleEndian.PutUint16(b[i*2:], r)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

(尽管这会比较慢,因为它会创建大量新的切片标头。)

\n