为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
眼眸繁星 2021-11-22 15:58:07
我是 Go 初学者,遇到了一个问题。我想用 UTF16 little endian 编码一个字符串,然后用 MD5(十六进制)对其进行散列。我找到了一段 Python 代码,它完全符合我的要求。但我无法将其转移到 Google Go。md5 = hashlib.md5()md5.update(challenge.encode('utf-16le'))response = md5.hexdigest()挑战是一个包含字符串的变量。
查看完整描述

3 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

您可以通过使用golang.org/x/text/encoding和golang.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)

}


查看完整回答
反对 回复 2021-11-22
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

您可以使用该unicode/utf16包进行 UTF-16 编码。utf16.Encode()返回 Unicode 代码点序列(符文片段:)的 UTF-16 编码[]rune。您可以简单地将 a 转换string为一段符文,例如[]rune("some string"),您可以通过覆盖uint16代码并首先发送/附加低字节然后将高字节发送/附加到输出(这是Little Endian 是什么意思)。


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


至于MD5校验和,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)

}

(虽然这会比较慢,因为它会创建很多新的切片标题。)


查看完整回答
反对 回复 2021-11-22
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

所以,作为参考,我使用了这个完整的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

}


查看完整回答
反对 回复 2021-11-22
  • 3 回答
  • 0 关注
  • 306 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信