Add hex2pcap

This commit is contained in:
2026-10-05 20:07:31 +02:00
parent 477e6c0ee7
commit 5b5cf211d0
19 changed files with 1694 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
// Package hexutil decodes hex strings in the loose formats people paste.
package hexutil
import (
"encoding/hex"
"fmt"
"strings"
)
// Decode decodes a hex string, tolerating common formatting:
// whitespace and newlines, ':' '-' ',' '.' separators, and "0x" / "\x" byte prefixes.
// So "45 00 00 3c", "45:00:00:3c", "0x45,0x00", "\x45\x00" and "4500003c" all work.
func Decode(s string) ([]byte, error) {
s = strings.NewReplacer(`\x`, " ", `\X`, " ", "0x", " ", "0X", " ").Replace(s)
digits := make([]byte, 0, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
switch {
case isHexDigit(c):
digits = append(digits, c)
case c == ' ' || c == '\t' || c == '\n' || c == '\r' ||
c == ':' || c == '-' || c == ',' || c == '.':
// separator
default:
return nil, fmt.Errorf("invalid character %q in hex input", c)
}
}
if len(digits)%2 != 0 {
return nil, fmt.Errorf("odd number of hex digits (%d)", len(digits))
}
out := make([]byte, len(digits)/2)
if _, err := hex.Decode(out, digits); err != nil {
return nil, err
}
return out, nil
}
func isHexDigit(c byte) bool {
return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F'
}
+44
View File
@@ -0,0 +1,44 @@
package hexutil
import (
"bytes"
"testing"
)
func TestDecode(t *testing.T) {
want := []byte{0x45, 0x00, 0x00, 0x3c}
for _, in := range []string{
"4500003c",
"45 00 00 3c",
"45:00:00:3C",
"45-00-00-3c",
"0x45, 0x00, 0x00, 0x3c",
`\x45\x00\x00\x3c`,
"4500\n003c\n",
" 45\t00 00\r\n3c ",
} {
got, err := Decode(in)
if err != nil {
t.Errorf("Decode(%q): %v", in, err)
continue
}
if !bytes.Equal(got, want) {
t.Errorf("Decode(%q) = %x, want %x", in, got, want)
}
}
}
func TestDecodeEmpty(t *testing.T) {
got, err := Decode(" \n ")
if err != nil || len(got) != 0 {
t.Errorf("Decode(blank) = %x, %v", got, err)
}
}
func TestDecodeErrors(t *testing.T) {
for _, in := range []string{"450", "45 0g", "45 00 zz"} {
if _, err := Decode(in); err == nil {
t.Errorf("Decode(%q): expected error", in)
}
}
}