Golang中字符串与[]byte的转换方法

Golang中字符串与[]byte的转换方法 为什么在Golang中将十六进制字符串转换为字节数组的结果与Java不同?

对于十六进制字符串 - 4CB178CC3FB92FB8693D31F1A39DB8C9

Java字节数组 - [76 -79 120 -52 63 -71 47 -72 105 61 49 -15 -93 -99 -72 -55]

Golang字节数组 - [76 177 120 204 63 185 47 184 105 61 49 241 163 157 184 201] (我在Golang中使用了encoding/hex包中的hex.DecodeString函数)

我想在Golang中获得与Java相同的字节数组。有人能帮忙吗?


更多关于Golang中字符串与[]byte的转换方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

检查Java转换,因为Go运行良好。假设B1=177。

更多关于Golang中字符串与[]byte的转换方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的,我明白了。非常感谢您提出的宝贵建议。同时也感谢其他人的帮助。

我想实现3DES加密。我正在使用Go语言,但由于字节值的差异,结果与Java(实际代码)不同。有没有办法在Go中获得与Java相同的字节数组?

Java使用有符号字节,而Go使用无符号字节,但它们在表示方式上是完全相同的(举例来说,177 + 79 = 256)。

问题是:你需要对它们进行什么操作?为什么打印格式很重要?

我坚持认为它们没有区别,它们是完全相同的字节数组。但如果你真的非常需要以相同的方式表示它们,只需按照我之前的回答所示,将字节转换为int8。

// 示例代码
func convertBytes(b []byte) []int8 {
    result := make([]int8, len(b))
    for i, v := range b {
        result[i] = int8(v)
    }
    return result
}

Java 的表现也不错,只是使用了不同的表示方式。Go 使用 uint8 表示字节,而 Java 使用 int8。请看以下示例,它将展示它们实际上是相同的(同时也提供了一种按“Java 方式”打印字节的方法,如果需要的话):

package main

import (
	"fmt"
)

func main() {
	var goByte byte = 177
	var javaByte = int8(goByte)
	fmt.Println(goByte)
	fmt.Println(javaByte)
}

或在 Go Playground 中查看:https://play.golang.org/p/JXPUkCFT9Vo

在Golang中,字节数组([]byte)默认使用无符号的uint8类型表示,范围是0-255;而Java的byte类型是有符号的,范围是-128到127。这就是为什么相同的十六进制数据在不同语言中显示为不同数值的原因。

实际上,这两个字节数组表示的是相同的二进制数据,只是显示方式不同。如果你需要在Golang中获得与Java相同的数值表示,可以进行类型转换。

以下是示例代码:

package main

import (
    "encoding/hex"
    "fmt"
)

func main() {
    hexStr := "4CB178CC3FB92FB8693D31F1A39DB8C9"
    
    // 使用hex.DecodeString解码十六进制字符串
    data, err := hex.DecodeString(hexStr)
    if err != nil {
        panic(err)
    }
    
    fmt.Println("Golang字节数组(无符号):", data)
    
    // 转换为有符号字节数组(与Java相同的表示)
    signedBytes := make([]int8, len(data))
    for i, b := range data {
        signedBytes[i] = int8(b)
    }
    
    fmt.Println("有符号字节数组(Java格式):", signedBytes)
    
    // 如果需要将负值转换回无符号表示
    unsignedBytes := make([]byte, len(signedBytes))
    for i, sb := range signedBytes {
        unsignedBytes[i] = byte(sb)
    }
    
    fmt.Println("转换回无符号字节:", unsignedBytes)
    
    // 验证数据是否相同
    fmt.Println("原始十六进制:", hexStr)
    fmt.Println("转换后十六进制:", hex.EncodeToString(unsignedBytes))
}

运行结果:

Golang字节数组(无符号): [76 177 120 204 63 185 47 184 105 61 49 241 163 157 184 201]
有符号字节数组(Java格式): [76 -79 120 -52 63 -71 47 -72 105 61 49 -15 -93 -99 -72 -55]
转换回无符号字节: [76 177 120 204 63 185 47 184 105 61 49 241 163 157 184 201]
原始十六进制: 4CB178CC3FB92FB8693D31F1A39DB8C9
转换后十六进制: 4cb178cc3fb92fb8693d31f1a39db8c9

关键点:

  • Golang的byteuint8的别名(无符号)
  • Java的byte是有符号的8位整数
  • 当值大于127时,在Java中会显示为负数(使用二进制补码表示)
  • 实际的二进制数据是完全相同的
回到顶部