From ee6b497e0ddeb186e7d0edff150ad8b6b52a87c3 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 26 Jun 2015 19:28:01 +0200 Subject: Add ASN.1 Integer coder/decoder --- ber/int.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ ber/int_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 ber/int.go create mode 100644 ber/int_test.go (limited to 'ber') diff --git a/ber/int.go b/ber/int.go new file mode 100644 index 0000000..32cc9af --- /dev/null +++ b/ber/int.go @@ -0,0 +1,46 @@ +package ber + +func intLen(i int) int { + n := 1 + for i > 255 { + n++ + i >>= 8 + } + for i < -256 { + n++ + i >>= 8 + } + return n +} + +func unmarshalInt(b []byte) (i int) { + nn := len(b) + neg := b[0]&0x80 != 0 + if b[0] == 0xFF { + b = b[1:] + nn -= 1 + } + for n, v := range b { + if neg { + v = ^v + } + i += int(v) << uint((nn-n-1)*8) + } + if neg { + i = -i - 1 + } + return +} + +func marshalInt(i int) (b []byte) { + for n := intLen(i); n > 0; n-- { + b = append(b, byte(i>>uint((n-1)*8))) + } + if i > 0 && b[0]&0x80 != 0 { + b = append([]byte{0x00}, b...) + } + if i < 0 && b[0]&0x80 == 0 { + b = append([]byte{0xFF}, b...) + } + return +} diff --git a/ber/int_test.go b/ber/int_test.go new file mode 100644 index 0000000..f0bd182 --- /dev/null +++ b/ber/int_test.go @@ -0,0 +1,32 @@ +package ber + +import ( + "testing" + "bytes" +) + +func test(t *testing.T, i int, b []byte) { + a := marshalInt(i) + if !bytes.Equal(a, b) { + t.Error("BER", i, "expected", b, "got", a) + } + + n := unmarshalInt(b) + if n != i { + t.Error("UnBER", b, "expected", i, "got", n) + } + +} + +func TestInt(t *testing.T) { + test(t, 0, []byte{0x00}) + test(t, 127, []byte{0x7F}) + test(t, 128, []byte{0x00, 0x80}) + test(t, 256, []byte{0x01, 0x00}) + test(t, -128, []byte{0x80}) + test(t, -129, []byte{0xFF, 0x7F}) + + test(t, 8388607, []byte{0x7f, 0xFF, 0xFF}) + test(t, -136, []byte{0xFF, 0x78}) + test(t, -8388607, []byte{0x80, 0x00, 0x01}) +} -- cgit v1.2.3