繁体   English   中英

Golang:验证字符串是否为有效的十六进制字符串?

[英]Golang: verify that string is a valid hex string?

我有一个结构:

type Name struct {
    hexID string
    age uint8
}

检查hexID字段是否为有效的十六进制字符串的最简单方法是什么? 如果没有 - 引发错误。

例如:

var n Name
n.hexID = "Hello World >)" // not a valid hex
n.hexID = "aaa12Eb9990101010101112cC" // valid hex

或者也许某处存在 struct tag

遍历字符串的字符,并检查每个字符是否都是有效的十六进制数字。

func isValidHex(s string) bool {
    for _, r := range s {
        if !(r >= '0' && r <= '9' || r >= 'a' && r <= 'f' || r >= 'A' && r <= 'F') {
            return false
        }
    }
    return true
}

测试它:

fmt.Println(isValidHex("Hello World >)"))
fmt.Println(isValidHex("aaa12Eb9990101010101112cC"))

Output(在Go 游乐场试试):

false
true

注意:您可能会想使用hex.DecodeString()并检查返回的错误:如果它是nil ,则它是有效的。 但请注意,这个 function 期望字符串具有偶数长度(因为它从十六进制数字和 2 个十六进制数字 forms 生成字节)一个字节)。 更不用说如果你不需要结果(作为字节片),这会更慢并且会产生不必要的垃圾(供 gc 收集)。

另一种解决方案可能是使用big.Int.SetString()

func isValidHex(s string) bool {
    _, ok := new(big.Int).SetString(s, 16)
    return ok
}

这输出相同,在Go Playground上试试。 但这再次变慢并且使用 memory 分配(产生垃圾)。

这个如何

regexp.MatchString("[^0-9A-Fa-f]", n.hexID)

如果字符串包含 HEX 非法字符则为真

评论:我现在完全不知道该用哪个了:( – armaka


不同的实现有不同的性能。 例如,

func isHexRock(s string) bool {
    for _, b := range []byte(s) {
        if !(b >= '0' && b <= '9' || b >= 'a' && b <= 'f' || b >= 'A' && b <= 'F') {
            return false
        }
    }
    return true
}

func isHexIcza(s string) bool {
    for _, r := range s {
        if !(r >= '0' && r <= '9' || r >= 'a' && r <= 'f' || r >= 'A' && r <= 'F') {
            return false
        }
    }
    return true
}

var rxNotHex = regexp.MustCompile("[^0-9A-Fa-f]")

func isHexOjacoGlobal(s string) bool {
    return !rxNotHex.MatchString(s)
}

func isHexOjacoLocal(s string) bool {
    notHex, err := regexp.MatchString("[^0-9A-Fa-f]", s)
    if err != nil {
        panic(err)
    }
    return !notHex
}

一些基准测试结果:

BenchmarkRock-4         36386997    30.92 ns/op     0 B/op   0 allocs/op
BenchmarkIcza-4         21100798    52.86 ns/op     0 B/op   0 allocs/op
BenchmarkOjacoGlobal-4   5958829   209.9 ns/op      0 B/op   0 allocs/op
BenchmarkOjacoLocal-4     227672  4648 ns/op     1626 B/op  22 allocs/op

我认为 ParseInt 方法也可以解决这个问题 -

    _, err := strconv.ParseInt("deadbeef", 16, 64)
    if err != nil {
       fmt.Println("not a hex string")
    } else {
    fmt.Println("it is a hex string")
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM