如何在 Go 中将 [Size]byte 转换为字符串?

Posted

技术标签:

【中文标题】如何在 Go 中将 [Size]byte 转换为字符串?【英文标题】:How do I convert [Size]byte to string in Go? 【发布时间】:2014-11-22 06:05:05 【问题描述】:

我在执行md5.Sum() 之后得到了一个大小合适的字节数组。

data := []byte("testing")
var pass string 
var b [16]byte
b = md5.Sum(data)
pass = string(b)

我得到错误:

无法将 b(类型 [16]byte)转换为类型字符串

【问题讨论】:

我想指出,在没有任何盐的情况下创建这样的密码是非常不安全的,也是个坏主意。 【参考方案1】:

不是为了打印十六进制编码的字符串,而是在一般的情况下[size]byte数组可能包含无效的UTF-8序列,那么根据this answer他们可以被转换使用

转换成有效的UTF-8
s := string([]rune(string(b[:])))

Example:

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() 
    b := [1]byte0xff
    s := string(b[:])
    fmt.Println(s, []byte(s), utf8.Valid([]byte(s)))
    // Output: � [255] false

    s = string([]rune(string(b[:])))
    fmt.Println(s, []byte(s), utf8.Valid([]byte(s)))
    // Output: � [239 191 189] true

【讨论】:

【参考方案2】:

你可以试试

b.decode("utf-8")

请告诉我,这对你有帮助吗? 强文本

【讨论】:

【参考方案3】:

虽然这里有一些简单的答案,但我想给出一个更有效的解决方案

```去 func Bytes2StrImp(b []byte) 字符串 sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b)) sh := reflect.StringHeader 数据:sliceHeader.Data, Len: sliceHeader.Len, return *(*string)(unsafe.Pointer(&sh)) // 审查错误可能误用 reflect.StringHeader ```

更新

func Bytes2StrImp(b []byte) string 
    sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    var s string
    sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
    sh.Data = sliceHeader.Data
    sh.Len = sliceHeader.Len
    return s

上述方案只是通过Pointer操作将字节数组转换为字符串。而string(b[:]) 将创建一个新的字符串对象并将数据从字节数组复制到字符串。

string(b[:]) 的基准测试结果

func Bytes2StrRaw(b []byte) string 
    return string(b[:])

BenchmarkBytes2StrRaw-12              275305142                4.40 ns/op
BenchmarkBytes2StrImp-12              1000000000               0.315 ns/op

【讨论】:

想解释一下那里发生了什么,为什么速度这么快? 此代码违反了golang.org/pkg/unsafe/#Pointer 的建议:“一般来说,reflect.SliceHeader 和 reflect.StringHeader 只能用作指向实际切片或字符串的 *reflect.SliceHeader 和 *reflect.StringHeader,从不作为普通结构。程序不应声明或分配这些结构类型的变量。" go vet 在当前版本中也抱怨 thi,例如在操场上尝试:play.golang.org/p/G6rRGp8jwtW 正确代码:play.golang.org/p/Lh28f4HF_W9 @RedowanDelowar,答案已更新。希望我清楚自己【参考方案4】:

可以这样解决

pass = fmt.Sprintf("%x", b)

import "encoding/base64"
pass = base64.StdEncoding.EncodeToString(b[:])

这会将其编码为 base64 字符串

【讨论】:

这是很多情况下的正确答案,不是公认的答案 感谢您提醒我[n]byte 表示数组,[]byte 表示切片!【参考方案5】:

有点晚,但请记住,使用 string(b[:]) 将打印大部分无效字符。

如果你想像 php 一样获得它的十六进制表示,你可以使用类似的东西:

data := []byte("testing")
b := md5.Sum(data)

//this is mostly invalid characters
fmt.Println(string(b[:]))

pass := hex.EncodeToString(b[:])
fmt.Println(pass)
// or
pass = fmt.Sprintf("%x", b)
fmt.Println(pass)

playground

【讨论】:

取决于您的打印方式。 @OneOfOne 你确定这是正确的方法。当我运行您提供的游乐场脚本时,我在输出中得到了这个。 �+�QYI��O�+��Uu ae2b1fca515949e5d54fb22b8ed95575 ae2b1fca515949e5d54fb22b8ed95575 @NikhilWagh 是正确的,第一个打印将是原始校验和,不适合打印,另外两个将是转换为十六进制的校验和。 为什么fmt.Println(string(b[:])) 会打印“大部分无效数据”? 这是接收 md5 哈希字符串的正确答案。其他一切都没有帮助..要求:import "encoding/hex"【参考方案6】:

您可以将其称为切片:

pass = string(b[:])

【讨论】:

【参考方案7】:

切一块:

pass = string(b[:])

【讨论】:

以上是关于如何在 Go 中将 [Size]byte 转换为字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Go中将字节数组转换为字符串[重复]

如何在 Go 中将 JSON 对象数组转换为具有默认值的结构数组?

在Swift中将bytes / UInt8数组转换为Int

如何在 C# 中将 Byte* 从 C++ 转换为 Byte[]

如何在 C 中将 wchar_t 转换为 BYTE*

如何在 C# 中将 List<byte> 转换为 byte[]?