如何在 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他们可以被转换使用
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 中将 JSON 对象数组转换为具有默认值的结构数组?