How do I convert [Size]byte to string in Go?

huangapple go评论89阅读模式
英文:

How do I convert [Size]byte to string in Go?

问题

我有一个经过md5.Sum()处理后得到的大小为16字节的字节数组。

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

我得到了以下错误信息:

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

英文:

I have a sized byte array that I got after doing md5.Sum().

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

I get the error:

>cannot convert b (type [16]byte) to type string

答案1

得分: 84

你可以将其称为切片:

pass = string(b[:])
英文:

You can refer to it as a slice:

pass = string(b[:])

答案2

得分: 52

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

如果你想像PHP一样得到一个十六进制表示,你可以使用类似下面的代码:

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

// 这将打印大部分无效字符
fmt.Println(string(b[:]))

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

playground

英文:

A little late but keep in mind that using string(b[:]) will print mostly invalid characters.

If you're trying to get a hex representation of it like php you can use something like:

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)

<kbd>playground</kbd>

答案3

得分: 14

这可以通过以下方式解决:

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

或者

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

这将把它编码为Base64字符串。

英文:

it can be solved by this

pass = fmt.Sprintf(&quot;%x&quot;, b)

or

import &quot;encoding/base64&quot;
pass = base64.StdEncoding.EncodeToString(b[:])

this will encoding it to base64 string

答案4

得分: 5

更新 2023年2月1日

根据这个unsafe: add StringData, String, SliceData问题,reflect.StringHeaderreflect.SliceHeader可能会在Go 1.20中被弃用。而unsafe.StringDataunsafe.Stringunsafe.SliceData将取而代之,请参考1.20版本发布说明

unsafe包定义了三个新函数SliceDataStringStringData。结合Go 1.17的Slice,这些函数现在提供了完整的构建和解构切片和字符串值的能力,而不依赖于它们的确切表示。

func String2Bytes(s string) []byte {
	if s == "" {
		return nil
	}
	return unsafe.Slice(unsafe.StringData(s), len(s))
}

func Bytes2String(b []byte) string {
	if len(b) == 0 {
		return ""
	}
	return unsafe.String(unsafe.SliceData(b), len(b))
}

Go 1.20之前

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
}

上述解决方案通过指针操作将字节数组转换为字符串。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

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

func Bytes2StrImp(b []byte) string{
	sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	sh := reflect.StringHeader{
		Data: sliceHeader.Data,
		Len:  sliceHeader.Len,
	}
	return *(*string)(unsafe.Pointer(&sh)) // go vet error possible misuse reflect.StringHeader
}


英文:

Update 02/01/2023

Per this, unsafe: add StringData, String, SliceData, the reflect.StringHeader and reflect.SliceHeader may be deprecated in Go 1.20. And the unsafe.StringData, unsafe.String, and unsafe.SliceData will replace them, refer to 1.20 release note

> The unsafe package defines three new functions SliceData, String, and StringData. Along with Go 1.17's Slice, these functions now provide the complete ability to construct and deconstruct slice and string values, without depending on their exact representation.

func String2Bytes(s string) []byte {
	if s == &quot;&quot; {
		return nil
	}
	return unsafe.Slice(unsafe.StringData(s), len(s))
}

func Bytes2String(b []byte) string {
	if len(b) == 0 {
		return &quot;&quot;
	}
	return unsafe.String(unsafe.SliceData(b), len(b))
}

Before Go 1.20

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

The above solution converts the byte array to string through Pointer operation. The string(b[:]) will do a new string object and copy data from the byte array to the string.

Benchmark result with string(b[:])

func Bytes2StrRaw(b []byte) string {
	return string(b[:])
}
BenchmarkBytes2StrRaw-12              275305142                4.40 ns/op
BenchmarkBytes2StrImp-12              1000000000               0.315 ns/op

Although there are some simple answers here, I want to give one more efficient solution

<strike>

func Bytes2StrImp(b []byte) string{
	sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&amp;b))
	sh := reflect.StringHeader{
		Data: sliceHeader.Data,
		Len:  sliceHeader.Len,
	}
	return *(*string)(unsafe.Pointer(&amp;sh)) // go vet error possible misuse reflect.StringHeader
}

</strike>


答案5

得分: 4

生成一个切片:

pass = string(b[:])
英文:

Make a slice of it:

pass = string(b[:])

答案6

得分: 0

不适用于打印十六进制编码的字符串,但在一般情况下,当[size]byte数组可能包含无效的UTF-8序列时,可以使用以下方法将其转换为有效的UTF-8字符串:

s := string([]rune(string(b[:])))

示例代码如下:

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	b := [1]byte{0xff}
	s := string(b[:])
	fmt.Println(s, []byte(s), utf8.Valid([]byte(s)))
	// 输出: � [255] false

	s = string([]rune(string(b[:])))
	fmt.Println(s, []byte(s), utf8.Valid([]byte(s)))
	// 输出: � [239 191 189] true
}
英文:

Not for printing hex-encoded strings, but in the general case when the [size]byte array may contain invalid UTF-8 sequence(s), then according to this answer they can be converted into valid UTF-8 using

s := string([]rune(string(b[:])))

Example:

package main

import (
	&quot;fmt&quot;
	&quot;unicode/utf8&quot;
)

func main() {
	b := [1]byte{0xff}
	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
}

答案7

得分: 0

我发现这些评论真的没有帮助,因为它们假设 OP 只想要一个字节切片的字面字符串...但如果你和我一样需要将 UTF-8 解码的字节作为字符串使用,你可以使用以下代码:

import "unicode/utf8"

func bytesToUtf8(b []byte) string {
    var myString = ""
    for i := 1; i <= len(b); i++ {
        r, _ := utf8.DecodeRune(b[i-1:i])
        myString += string(r)
    }
    return myString
}

var uselessBytes := []byte{123,34,...}
helpfulUtf8String := bytesToUtf8(uselessBytes)
英文:

I found these comments really unhelpful because they assume OP just wants a literal string of the []byte.... but if you were like me and need utf8 decoded bytes as a string you can use this:

import  &quot;unicode/utf8&quot;
func bytesToUtf8(b []byte) string {
	var myString = &quot;&quot;;
	for i := 1; i &lt;= len(b); i++ {
		r, _ := utf8.DecodeRune(b[i-1:i])
		myString += string(r)
	}
	return myString
}
var uselessBytes := []byte{123,34,...}
helpfulUtf8String := bytesToUtf8(uselessBytes)

答案8

得分: -3

你可以尝试以下代码:

<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
    b.decode("utf-8")
<!-- end snippet -->

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

英文:

you can try

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

b.decode(&quot;utf-8&quot;)

<!-- end snippet -->

please let me know, is that help you or not?
strong text

huangapple
  • 本文由 发表于 2014年9月27日 16:43:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/26072921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定