英文:
Sum hexadecimal on Golang
问题
感谢阅读我的问题。
我正在尝试在Golang中计算ASTM校验和,但无法弄清楚如何将字符串或字节转换为可由自己和Google计算的十六进制数。
请允许我请求帮助,谢谢。
在Golang中,如何将字符转换为可进行求和的十六进制数?
示例:
// 将字符"a"转换为十六进制0x61(我知道这对我的情况不起作用,因为它变成了一个字符串。)
hex := fmt.Sprintf("%x", "a")
// 将0x61与0x01相加,所以它将变成0x62 = "b"
fmt.Printf("%v", hex + 0x01)
非常感谢,请度过愉快的一天。
感谢所有回答我的问题!peterSO和ANisus的答案都解决了我的问题。请允许我选择ANisus的回答作为答案,因为它包含了ASTM特殊字符。我希望StackOverflow可以选择多个答案。感谢所有回答我的人,请度过愉快的一天!
英文:
Thanks for reading my question.
I am trying to count ASTM checksum on Golang but couldn't figure it out how to convert string or byte to hexadecimal that is countable by myself and Google.
Please let me request help, thanks.
At Golang, how to convert a character to hexadecimal that can allow performing a sum?
Example:
// Convert character "a" to hex 0x61 ( I understand this will not work for my case as it became a string.)
hex := fmt.Sprintf("%x","a")
// sum the 0x61 with 0x01 so it will become 0x62 = "b"
fmt.Printf("%v",hex + 0x01)
Thank you so much and please have a nice day.
Thanks for everyone answering my question! peterSO and ANisus answers both solved my problem. Please let me choose ANisus's reply as answer as it including ASTM special character in it. I wish StackOverflow could choose multiple answers. Thanks for everybody answering me and please have a nice day!
答案1
得分: 2
Intermernet的答案展示了如何将十六进制字符串转换为整数值。
但是,你的问题似乎暗示你想要获取字母'a'的码点值,然后对该值进行算术运算。为了做到这一点,你不需要使用十六进制。你可以按照以下方式操作:
package main
import "fmt"
func main() {
// 获取字母'a'的码点值,即0x61
val := 'a'
// 将0x61与0x01相加,得到0x62,即'b'
fmt.Printf("%v", string(val + 0x01))
}
结果:
b
Playground: http://play.golang.org/p/SbsUHIcrXK
编辑:
使用描述在这里的算法对字符串进行实际的ASTM校验和计算可以使用以下代码完成:
package main
import (
"fmt"
)
const (
ETX = 0x03
ETB = 23
STX = 0x02
)
func ASTMCheckSum(frame string) string {
var sumOfChars uint8
// 对字符串中的每个字节进行求和
for i := 0; i < len(frame) ; i++ {
byteVal := frame[i]
sumOfChars += byteVal
if byteVal == STX {
sumOfChars = 0
}
if byteVal == ETX || byteVal == ETB {
break
}
}
// 以大写十六进制形式返回
return fmt.Sprintf("%02X", sumOfChars)
}
func main() {
data := "\x025R|2|^^^1.0000+950+1.0|15|||^5^||V||34001637|20080516153540|20080516153602|34001637\r\x033D\r\n"
//fmt.Println(data)
fmt.Println(ASTMCheckSum(data))
}
结果:
3D
Playground: http://play.golang.org/p/7cbwryZk8r
英文:
Intermernet's answer shows you how to convert a hexadecimal string into an int value.
But your question seems to suggest that you want to want to get the code point value of the letter 'a' and then do aritmetics on that value. To do this, you don't need hexadecimal. You can do the following:
package main
import "fmt"
func main() {
// Get the code point value of 'a' which is 0x61
val := 'a'
// sum the 0x61 with 0x01 so it will become 0x62 = 'b'
fmt.Printf("%v", string(val + 0x01))
}
Result:
>b
Playground: http://play.golang.org/p/SbsUHIcrXK
Edit:
Doing the actual ASTM checksum from a string using the algorithm described here can be done with the following code:
package main
import (
"fmt"
)
const (
ETX = 0x03
ETB = 23
STX = 0x02
)
func ASTMCheckSum(frame string) string {
var sumOfChars uint8
//take each byte in the string and add the values
for i := 0; i < len(frame) ; i++ {
byteVal := frame[i]
sumOfChars += byteVal
if byteVal == STX {
sumOfChars = 0
}
if byteVal == ETX || byteVal == ETB {
break
}
}
// return as hex value in upper case
return fmt.Sprintf("%02X", sumOfChars)
}
func main() {
data := "\x025R|2|^^^1.0000+950+1.0|15|||^5^||V||34001637|20080516153540|20080516153602|34001637\r\x033D\r\n"
//fmt.Println(data)
fmt.Println(ASTMCheckSum(data))
}
Result:
>3D
Playground: http://play.golang.org/p/7cbwryZk8r
答案2
得分: 1
ParseInt
函数将给定进制(2到36)中的字符串s
解析为相应的值i
。如果base == 0
,则进制由字符串的前缀隐含确定:对于"0x",进制为16;对于"0",进制为8;否则进制为10。
package main
import (
"fmt"
"strconv"
)
func main() {
start := "a"
result, err := strconv.ParseInt(start, 16, 0)
if err != nil {
panic(err)
}
fmt.Printf("%x", result+1)
}
英文:
You can use ParseInt
from the strconv
package.
>ParseInt interprets a string s in the given base (2 to 36) and returns the corresponding value i. If base == 0, the base is implied by the string's prefix: base 16 for "0x", base 8 for "0", and base 10 otherwise.
package main
import (
"fmt"
"strconv"
)
func main() {
start := "a"
result, err := strconv.ParseInt(start, 16, 0)
if err != nil {
panic(err)
}
fmt.Printf("%x", result+1)
}
答案3
得分: 0
例如,
package main
import "fmt"
func ASTMCheckSum(data []byte) []byte {
cs := byte(0)
for _, b := range data {
cs += b
}
return []byte(fmt.Sprintf("%02X", cs))
}
func main() {
data := []byte{0x01, 0x08, 0x1f, 0xff, 0x07}
fmt.Printf("%x\n", data)
cs := ASTMCheckSum(data)
fmt.Printf("%s\n", cs)
}
输出:
01081fff07
2E
英文:
For example,
package main
import "fmt"
func ASTMCheckSum(data []byte) []byte {
cs := byte(0)
for _, b := range data {
cs += b
}
return []byte(fmt.Sprintf("%02X", cs))
}
func main() {
data := []byte{0x01, 0x08, 0x1f, 0xff, 0x07}
fmt.Printf("%x\n", data)
cs := ASTMCheckSum(data)
fmt.Printf("%s\n", cs)
}
Output:
01081fff07
2E
答案4
得分: 0
你不想将字符转换为十六进制,因为十六进制(以及十进制、二进制和其他所有基于N的整数表示)是用来向人类显示数字和消费数字的。计算机可以自由地以任何形式存储它所操作的数字;虽然大多数(全部?)现实世界的计算机以二进制形式存储它们-使用位,但它们不必这样做。
我要引导你的是,你实际上想要将用十六进制表示的字符("显示形式")转换为数字(计算机所操作的)。为此,你可以使用已经建议的strconv
包,或者编写自己的简单转换代码。或者你可以直接从encoding/hex
标准包中获取一个-看看它的fromHexChar
函数。
英文:
You do not want to "convert a character to hex" because hexadecimal (and decimal and binary and all other base-N representations of integers) are here for displaying numbers to humans and consuming them back. A computer is free to actually store the number it operates on in any form it wishes; while most (all?) real-world computers store them in binary form—using bits, they don't have to.
What I'm leading you to, is that you actually want to convert your character representing a number using hexadecimal notation ("display form") to a number (what computers operate on). For this, you can either use the strconv
package as already suggested or roll your own simple conversion code. Or you can just grab one from the encoding/hex
standard package—see its fromHexChar
function.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论