410 lines
12 KiB
Nim
410 lines
12 KiB
Nim
import unittest
|
|
import ../stew/base32
|
|
|
|
when defined(nimHasUsed): {.used.}
|
|
|
|
const TVBaseUpperPadding = [
|
|
["f", "MY======"],
|
|
["fo", "MZXQ===="],
|
|
["foo", "MZXW6==="],
|
|
["foob", "MZXW6YQ="],
|
|
["fooba", "MZXW6YTB"],
|
|
["foobar", "MZXW6YTBOI======"]
|
|
]
|
|
|
|
const TVBaseUpperNoPadding = [
|
|
["f", "MY"],
|
|
["fo", "MZXQ"],
|
|
["foo", "MZXW6"],
|
|
["foob", "MZXW6YQ"],
|
|
["fooba", "MZXW6YTB"],
|
|
["foobar", "MZXW6YTBOI"]
|
|
]
|
|
|
|
const TVBaseLowerPadding = [
|
|
["f", "my======"],
|
|
["fo", "mzxq===="],
|
|
["foo", "mzxw6==="],
|
|
["foob", "mzxw6yq="],
|
|
["fooba", "mzxw6ytb"],
|
|
["foobar", "mzxw6ytboi======"]
|
|
]
|
|
|
|
const TVBaseLowerNoPadding = [
|
|
["f", "my"],
|
|
["fo", "mzxq"],
|
|
["foo", "mzxw6"],
|
|
["foob", "mzxw6yq"],
|
|
["fooba", "mzxw6ytb"],
|
|
["foobar", "mzxw6ytboi"]
|
|
]
|
|
|
|
const TVHexUpperPadding = [
|
|
["f", "CO======"],
|
|
["fo", "CPNG===="],
|
|
["foo", "CPNMU==="],
|
|
["foob", "CPNMUOG="],
|
|
["fooba", "CPNMUOJ1"],
|
|
["foobar", "CPNMUOJ1E8======"]
|
|
]
|
|
|
|
const TVHexUpperNoPadding = [
|
|
["f", "CO"],
|
|
["fo", "CPNG"],
|
|
["foo", "CPNMU"],
|
|
["foob", "CPNMUOG"],
|
|
["fooba", "CPNMUOJ1"],
|
|
["foobar", "CPNMUOJ1E8"]
|
|
]
|
|
|
|
const TVHexLowerPadding = [
|
|
["f", "co======"],
|
|
["fo", "cpng===="],
|
|
["foo", "cpnmu==="],
|
|
["foob", "cpnmuog="],
|
|
["fooba", "cpnmuoj1"],
|
|
["foobar", "cpnmuoj1e8======"]
|
|
]
|
|
|
|
const TVHexLowerNoPadding = [
|
|
["f", "co"],
|
|
["fo", "cpng"],
|
|
["foo", "cpnmu"],
|
|
["foob", "cpnmuog"],
|
|
["fooba", "cpnmuoj1"],
|
|
["foobar", "cpnmuoj1e8"]
|
|
]
|
|
|
|
suite "BASE32 encoding test suite":
|
|
test "Empty seq/string test":
|
|
var empty1 = newSeq[byte]()
|
|
var empty2 = ""
|
|
var encoded = newString(16)
|
|
var decoded = newSeq[byte](16)
|
|
|
|
var o1, o2, o3, o4, o5, o6, o7, o8: int
|
|
var e1 = Base32Upper.encode(empty1)
|
|
var e2 = Base32Lower.encode(empty1)
|
|
var e3 = Base32UpperPad.encode(empty1)
|
|
var e4 = Base32LowerPad.encode(empty1)
|
|
var e5 = HexBase32Upper.encode(empty1)
|
|
var e6 = HexBase32Lower.encode(empty1)
|
|
var e7 = HexBase32UpperPad.encode(empty1)
|
|
var e8 = HexBase32LowerPad.encode(empty1)
|
|
check:
|
|
Base32Upper.encode(empty1, encoded, o1) == Base32Status.Success
|
|
Base32Lower.encode(empty1, encoded, o2) == Base32Status.Success
|
|
Base32UpperPad.encode(empty1, encoded, o3) == Base32Status.Success
|
|
Base32LowerPad.encode(empty1, encoded, o4) == Base32Status.Success
|
|
HexBase32Upper.encode(empty1, encoded, o5) == Base32Status.Success
|
|
HexBase32Lower.encode(empty1, encoded, o6) == Base32Status.Success
|
|
HexBase32UpperPad.encode(empty1, encoded, o7) == Base32Status.Success
|
|
HexBase32LowerPad.encode(empty1, encoded, o8) == Base32Status.Success
|
|
len(e1) == 0
|
|
len(e2) == 0
|
|
len(e3) == 0
|
|
len(e4) == 0
|
|
len(e5) == 0
|
|
len(e6) == 0
|
|
len(e7) == 0
|
|
len(e8) == 0
|
|
o1 == 0
|
|
o2 == 0
|
|
o3 == 0
|
|
o4 == 0
|
|
o5 == 0
|
|
o6 == 0
|
|
o7 == 0
|
|
o8 == 0
|
|
var d1 = Base32Upper.decode("")
|
|
var d2 = Base32Lower.decode("")
|
|
var d3 = Base32UpperPad.decode("")
|
|
var d4 = Base32LowerPad.decode("")
|
|
var d5 = HexBase32Upper.decode("")
|
|
var d6 = HexBase32Lower.decode("")
|
|
var d7 = HexBase32UpperPad.decode("")
|
|
var d8 = HexBase32LowerPad.decode("")
|
|
check:
|
|
Base32Upper.decode(empty2, decoded, o1) == Base32Status.Success
|
|
Base32Lower.decode(empty2, decoded, o2) == Base32Status.Success
|
|
Base32UpperPad.decode(empty2, decoded, o3) == Base32Status.Success
|
|
Base32LowerPad.decode(empty2, decoded, o4) == Base32Status.Success
|
|
HexBase32Upper.decode(empty2, decoded, o5) == Base32Status.Success
|
|
HexBase32Lower.decode(empty2, decoded, o6) == Base32Status.Success
|
|
HexBase32UpperPad.decode(empty2, decoded, o7) == Base32Status.Success
|
|
HexBase32LowerPad.decode(empty2, decoded, o8) == Base32Status.Success
|
|
len(d1) == 0
|
|
len(d2) == 0
|
|
len(d3) == 0
|
|
len(d4) == 0
|
|
len(d5) == 0
|
|
len(d6) == 0
|
|
len(d7) == 0
|
|
len(d8) == 0
|
|
o1 == 0
|
|
o2 == 0
|
|
o3 == 0
|
|
o4 == 0
|
|
o5 == 0
|
|
o6 == 0
|
|
o7 == 0
|
|
o8 == 0
|
|
|
|
test "Zero test":
|
|
var s = newString(256)
|
|
for i in 0..255:
|
|
s[i] = 'A'
|
|
var buffer: array[256, byte]
|
|
for i in 0..255:
|
|
var a = Base32.encode(buffer.toOpenArray(0, i))
|
|
var b = Base32.decode(a)
|
|
check b == buffer[0..i]
|
|
|
|
test "Leading zero test":
|
|
var buffer: array[256, byte]
|
|
for i in 0..255:
|
|
buffer[255] = byte(i)
|
|
var a = Base32.encode(buffer)
|
|
var b = Base32.decode(a)
|
|
check:
|
|
equalMem(addr buffer[0], addr b[0], 256) == true
|
|
|
|
test "BASE32 uppercase padding test vectors":
|
|
for item in TVBaseUpperPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = Base32UpperPad.encode(plain)
|
|
var e2 = newString(Base32UpperPad.encodedLength(len(plain)))
|
|
check:
|
|
Base32UpperPad.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = Base32UpperPad.decode(expect)
|
|
var d2 = newSeq[byte](Base32UpperPad.decodedLength(len(expect)))
|
|
check:
|
|
Base32UpperPad.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "BASE32 lowercase padding test vectors":
|
|
for item in TVBaseLowerPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = Base32LowerPad.encode(plain)
|
|
var e2 = newString(Base32LowerPad.encodedLength(len(plain)))
|
|
check:
|
|
Base32LowerPad.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = Base32LowerPad.decode(expect)
|
|
var d2 = newSeq[byte](Base32LowerPad.decodedLength(len(expect)))
|
|
check:
|
|
Base32LowerPad.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "BASE32 uppercase no-padding test vectors":
|
|
for item in TVBaseUpperNoPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = Base32Upper.encode(plain)
|
|
var e2 = newString(Base32Upper.encodedLength(len(plain)))
|
|
check:
|
|
Base32Upper.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = Base32Upper.decode(expect)
|
|
var d2 = newSeq[byte](Base32Upper.decodedLength(len(expect)))
|
|
check:
|
|
Base32Upper.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "BASE32 lowercase no-padding test vectors":
|
|
for item in TVBaseLowerNoPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = Base32Lower.encode(plain)
|
|
var e2 = newString(Base32Lower.encodedLength(len(plain)))
|
|
check:
|
|
Base32Lower.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = Base32Lower.decode(expect)
|
|
var d2 = newSeq[byte](Base32Lower.decodedLength(len(expect)))
|
|
check:
|
|
Base32Lower.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "HEX-BASE32 uppercase padding test vectors":
|
|
for item in TVHexUpperPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = HexBase32UpperPad.encode(plain)
|
|
var e2 = newString(HexBase32UpperPad.encodedLength(len(plain)))
|
|
check:
|
|
HexBase32UpperPad.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = HexBase32UpperPad.decode(expect)
|
|
var d2 = newSeq[byte](HexBase32UpperPad.decodedLength(len(expect)))
|
|
check:
|
|
HexBase32UpperPad.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "HEX-BASE32 lowercase padding test vectors":
|
|
for item in TVHexLowerPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = HexBase32LowerPad.encode(plain)
|
|
var e2 = newString(HexBase32LowerPad.encodedLength(len(plain)))
|
|
check:
|
|
HexBase32LowerPad.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = HexBase32LowerPad.decode(expect)
|
|
var d2 = newSeq[byte](HexBase32LowerPad.decodedLength(len(expect)))
|
|
check:
|
|
HexBase32LowerPad.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "HEX-BASE32 uppercase no-padding test vectors":
|
|
for item in TVHexUpperNoPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = HexBase32Upper.encode(plain)
|
|
var e2 = newString(HexBase32Upper.encodedLength(len(plain)))
|
|
check:
|
|
HexBase32Upper.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = HexBase32Upper.decode(expect)
|
|
var d2 = newSeq[byte](HexBase32Upper.decodedLength(len(expect)))
|
|
check:
|
|
HexBase32Upper.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "HEX-BASE32 lowercase no-padding test vectors":
|
|
for item in TVHexLowerNoPadding:
|
|
let plain = cast[seq[byte]](item[0])
|
|
let expect = item[1]
|
|
var elen = 0
|
|
var dlen = 0
|
|
|
|
var e1 = HexBase32Lower.encode(plain)
|
|
var e2 = newString(HexBase32Lower.encodedLength(len(plain)))
|
|
check:
|
|
HexBase32Lower.encode(plain, e2, elen) == Base32Status.Success
|
|
e2.setLen(elen)
|
|
check:
|
|
e1 == expect
|
|
e2 == expect
|
|
|
|
var d1 = HexBase32Lower.decode(expect)
|
|
var d2 = newSeq[byte](HexBase32Lower.decodedLength(len(expect)))
|
|
check:
|
|
HexBase32Lower.decode(expect, d2, dlen) == Base32Status.Success
|
|
d2.setLen(dlen)
|
|
check:
|
|
d1 == plain
|
|
d2 == plain
|
|
|
|
test "Buffer Overrun test":
|
|
var encres = ""
|
|
var encsize = 0
|
|
var decres: seq[byte] = @[]
|
|
var decsize = 0
|
|
check:
|
|
Base32.encode([0'u8], encres, encsize) == Base32Status.Overrun
|
|
encsize == Base32.encodedLength(1)
|
|
Base32.decode("AA", decres, decsize) == Base32Status.Overrun
|
|
decsize == Base32.decodedLength(2)
|
|
|
|
test "Incorrect test":
|
|
var decres = newSeq[byte](10)
|
|
var decsize = 0
|
|
check:
|
|
Base32.decode("A", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
Base32.decode("AAA", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
Base32.decode("AAAAAA", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
Base32Upper.decode("aa", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
Base32Upper.decode("11", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
Base32Lower.decode("AA", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
Base32Lower.decode("11", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
HexBase32Upper.decode("aa", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
HexBase32Upper.decode("WW", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
HexBase32Lower.decode("AA", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
HexBase32Lower.decode("ww", decres, decsize) == Base32Status.Incorrect
|
|
decsize == 0
|
|
|