Add base64 and tests for it.

Adopt multibase to be able to use base64.
Fix base32 typos.
This commit is contained in:
cheatfate 2019-03-06 02:36:09 +02:00
parent d7a7f8102d
commit 39129d0ec1
No known key found for this signature in database
GPG Key ID: 46ADD633A7201F95
6 changed files with 518 additions and 61 deletions

View File

@ -15,6 +15,7 @@ task test, "Runs the test suite":
exec "nim c -r tests/testvarint" exec "nim c -r tests/testvarint"
exec "nim c -r tests/testbase58" exec "nim c -r tests/testbase58"
exec "nim c -r tests/testbase32" exec "nim c -r tests/testbase32"
exec "nim c -r tests/testbase64"
exec "nim c -r tests/testmultiaddress" exec "nim c -r tests/testmultiaddress"
exec "nim c -r tests/testmultihash" exec "nim c -r tests/testmultihash"
exec "nim c -r tests/testmultibase" exec "nim c -r tests/testmultibase"

View File

@ -22,23 +22,23 @@ type
encode*: array[32, uint8] encode*: array[32, uint8]
Base32Upper* = object Base32Upper* = object
## Type to use RFC4868 alphabet in uppercase without padding ## Type to use RFC4648 alphabet in uppercase without padding
Base32Lower* = object Base32Lower* = object
## Type to use RFC4868 alphabet in lowercase without padding ## Type to use RFC4648 alphabet in lowercase without padding
Base32UpperPad* = object Base32UpperPad* = object
## Type to use RFC4868 alphabet in uppercase with padding ## Type to use RFC4648 alphabet in uppercase with padding
Base32LowerPad* = object Base32LowerPad* = object
## Type to use RFC4868 alphabet in lowercase with padding ## Type to use RFC4648 alphabet in lowercase with padding
HexBase32Upper* = object HexBase32Upper* = object
## Type to use RFC4868-HEX alphabet in uppercase without padding ## Type to use RFC4648-HEX alphabet in uppercase without padding
HexBase32Lower* = object HexBase32Lower* = object
## Type to use RFC4868-HEX alphabet in lowercase without padding ## Type to use RFC4648-HEX alphabet in lowercase without padding
HexBase32UpperPad* = object HexBase32UpperPad* = object
## Type to use RFC4868-HEX alphabet in uppercase with padding ## Type to use RFC4648-HEX alphabet in uppercase with padding
HexBase32LowerPad* = object HexBase32LowerPad* = object
## Type to use RFC4868-HEX alphabet in lowercase with padding ## Type to use RFC4648-HEX alphabet in lowercase with padding
Base32* = Base32Upper Base32* = Base32Upper
## By default we are using RFC4868 alphabet in uppercase without padding ## By default we are using RFC4648 alphabet in uppercase without padding
Base32PadTypes* = Base32UpperPad | Base32LowerPad | Base32PadTypes* = Base32UpperPad | Base32LowerPad |
HexBase32UpperPad | HexBase32LowerPad HexBase32UpperPad | HexBase32LowerPad
## All types with padding support ## All types with padding support
@ -240,12 +240,10 @@ proc decode*[T: byte|char](btype: typedesc[Base32Types], instr: openarray[T],
for j in 0..<8: for j in 0..<8:
if (cast[byte](instr[i + j]) and 0x80'u8) != 0: if (cast[byte](instr[i + j]) and 0x80'u8) != 0:
outlen = 0 outlen = 0
zeroMem(addr outbytes[0], i + 8)
return Base32Status.Incorrect return Base32Status.Incorrect
let ch = alphabet.decode[int8(instr[i + j])] let ch = alphabet.decode[cast[int8](instr[i + j])]
if ch == -1: if ch == -1:
outlen = 0 outlen = 0
zeroMem(addr outbytes[0], i + 8)
return Base32Status.Incorrect return Base32Status.Incorrect
buffer[j] = cast[byte](ch) buffer[j] = cast[byte](ch)
discard convert8to5(buffer, outbytes.toOpenArray(k, k + 4), 8) discard convert8to5(buffer, outbytes.toOpenArray(k, k + 4), 8)
@ -256,18 +254,15 @@ proc decode*[T: byte|char](btype: typedesc[Base32Types], instr: openarray[T],
if reminder != 0: if reminder != 0:
if reminder == 1 or reminder == 3 or reminder == 6: if reminder == 1 or reminder == 3 or reminder == 6:
outlen = 0 outlen = 0
zeroMem(addr outbytes[0], i + 8)
return Base32Status.Incorrect return Base32Status.Incorrect
for j in 0..<reminder: for j in 0..<reminder:
if (cast[byte](instr[i + j]) and 0x80'u8) != 0: if (cast[byte](instr[i + j]) and 0x80'u8) != 0:
outlen = 0 outlen = 0
zeroMem(addr outbytes[0], i + 8)
result = Base32Status.Incorrect result = Base32Status.Incorrect
return return
let ch = alphabet.decode[int8(instr[i + j])] let ch = alphabet.decode[cast[int8](instr[i + j])]
if ch == -1: if ch == -1:
outlen = 0 outlen = 0
zeroMem(addr outbytes[0], i + 8)
result = Base32Status.Incorrect result = Base32Status.Incorrect
return return
buffer[j] = cast[byte](ch) buffer[j] = cast[byte](ch)
@ -287,4 +282,4 @@ proc decode*[T: byte|char](btype: typedesc[Base32Types],
if btype.decode(instr, result, length) == Base32Status.Success: if btype.decode(instr, result, length) == Base32Status.Success:
result.setLen(length) result.setLen(length)
else: else:
raise newException(Base32Error, "Incorrect base58 string") raise newException(Base32Error, "Incorrect base32 string")

238
libp2p/base64.nim Normal file
View File

@ -0,0 +1,238 @@
## Nim-Libp2p
## Copyright (c) 2018 Status Research & Development GmbH
## Licensed under either of
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
## at your option.
## This file may not be copied, modified, or distributed except according to
## those terms.
## This module implements BASE64 encoding and decoding procedures.
type
Base64Status* {.pure.} = enum
Error,
Success,
Incorrect,
Overrun
Base64Alphabet* = object
decode*: array[128, int8]
encode*: array[64, uint8]
Base64* = object
## Type to use RFC4648 alphabet without padding
Base64Pad* = object
## Type to use RFC4648 alphabet with padding
Base64Url* = object
## Type to use RFC4648 URL alphabet without padding
Base64UrlPad* = object
## Type to use RFC4648 URL alphabet with padding
Base64PadTypes* = Base64Pad | Base64UrlPad
## All types with padding support
Base64NoPadTypes* = Base64 | Base64Url
## All types without padding support
Base64Types* = Base64 | Base64Pad | Base64Url | Base64UrlPad
## All types
Base64Error* = object of Exception
## Base64 specific exception type
proc newAlphabet64*(s: string): Base64Alphabet =
doAssert(len(s) == 64)
for i in 0..<len(s):
result.encode[i] = cast[uint8](s[i])
for i in 0..<len(result.decode):
result.decode[i] = -1
for i in 0..<len(result.encode):
result.decode[int(result.encode[i])] = int8(i)
const
B64Alphabet* = newAlphabet64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" &
"ghijklmnopqrstuvwxyz0123456789+/")
B64UrlAlphabet* = newAlphabet64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" &
"ghijklmnopqrstuvwxyz0123456789-_")
proc encodedLength*(btype: typedesc[Base64Types],
length: int): int {.inline.} =
## Return estimated length of BASE64 encoded value for plain length
## ``length``.
result = (((length + 2) div 3) * 4) + 1
proc decodedLength*(btype: typedesc[Base64Types],
length: int): int {.inline.} =
## Return estimated length of decoded value of BASE64 encoded value of length
## ``length``.
when (btype is Base64Pad) or (btype is Base64UrlPad):
result = ((length + 3 - 1) div 3) * 4
elif (btype is Base64) or (btype is Base64Url):
result = (length * 4 + 3 - 1) div 3
proc encode*(btype: typedesc[Base64Types], inbytes: openarray[byte],
outstr: var openarray[char], outlen: var int): Base64Status =
## Encode array of bytes ``inbytes`` using BASE64 encoding and store
## result to ``outstr``.
##
## On success ``Base64Status.Success`` will be returned and ``outlen`` will
## be set to number of characters stored inside of ``outstr``.
##
## If length of ``outstr`` is not enough then ``Base64Status.Overrun`` will
## be returned and ``outlen`` will be set to number of characters required.
when (btype is Base64) or (btype is Base64Pad):
const alphabet = B64Alphabet
elif (btype is Base64Url) or (btype is Base64UrlPad):
const alphabet = B64UrlAlphabet
let length = len(inbytes)
if len(outstr) < btype.encodedLength(length):
outlen = btype.encodedLength(length)
result = Base64Status.Overrun
else:
var offset = 0
var i = 0
while i < (length - 2):
outstr[offset] = chr(alphabet.encode[(inbytes[i] shr 2) and 0x3F'u8])
inc(offset)
outstr[offset] = chr(alphabet.encode[((inbytes[i] and 0x03) shl 4) or
((inbytes[i + 1] and 0xF0) shr 4)])
inc(offset)
outstr[offset] = chr(alphabet.encode[((inbytes[i + 1] and 0x0F) shl 2) or
((inbytes[i + 2] and 0xC0) shr 6)])
inc(offset)
outstr[offset] = chr(alphabet.encode[inbytes[i + 2] and 0x3F])
inc(offset)
i += 3
if i < length:
outstr[offset] = chr(alphabet.encode[(inbytes[i] shr 2) and 0x3F])
inc(offset)
if i == length - 1:
outstr[offset] = chr(alphabet.encode[(inbytes[i] and 0x03) shl 4])
inc(offset)
when (btype is Base64Pad) or (btype is Base64UrlPad):
outstr[offset] = '='
inc(offset)
else:
outstr[offset] = chr(alphabet.encode[((inbytes[i] and 0x03) shl 4) or
((inbytes[i + 1] and 0xF0) shr 4)])
inc(offset)
outstr[offset] = chr(alphabet.encode[(inbytes[i + 1] and 0x0F) shl 2])
inc(offset)
when (btype is Base64Pad) or (btype is Base64UrlPad):
outstr[offset] = '='
inc(offset)
outlen = offset
result = Base64Status.Success
proc encode*(btype: typedesc[Base64Types],
inbytes: openarray[byte]): string {.inline.} =
## Encode array of bytes ``inbytes`` using BASE64 encoding and return
## encoded string.
var size = btype.encodedLength(len(inbytes))
result = newString(size)
if btype.encode(inbytes, result.toOpenArray(0, size - 1),
size) == Base64Status.Success:
result.setLen(size)
else:
result = ""
proc decode*[T: byte|char](btype: typedesc[Base64Types], instr: openarray[T],
outbytes: var openarray[byte], outlen: var int): Base64Status =
## Decode BASE64 string and store array of bytes to ``outbytes``. On success
## ``Base64Status.Success`` will be returned and ``outlen`` will be set
## to number of bytes stored.
##
## Length of ``outbytes`` must be equal or more then ``len(instr) + 4``.
##
## If ``instr`` has characters which are not part of BASE64 alphabet, then
## ``Base64Status.Incorrect`` will be returned and ``outlen`` will be set to
## ``0``.
##
## If length of ``outbytes`` is not enough to store decoded bytes, then
## ``Base64Status.Overrun`` will be returned and ``outlen`` will be set to
## number of bytes required.
when (btype is Base64) or (btype is Base64Pad):
const alphabet = B64Alphabet
elif (btype is Base64Url) or (btype is Base64UrlPad):
const alphabet = B64UrlAlphabet
if len(instr) == 0:
outlen = 0
return Base64Status.Success
let length = btype.decodedLength(len(instr))
if length > len(outbytes):
outlen = length
return Base64Status.Overrun
var inlen = len(instr)
when (btype is Base64PadTypes):
for i in countdown(inlen - 1, 0):
if instr[i] != '=':
break
dec(inlen)
let reminder = inlen mod 4
let limit = inlen - reminder
var buffer: array[4, byte]
var i, k: int
while i < limit:
for j in 0..<4:
if (cast[byte](instr[i + j]) and 0x80'u8) != 0:
outlen = 0
zeroMem(addr outbytes[0], i + 3)
return Base64Status.Incorrect
let ch = alphabet.decode[cast[int8](instr[i + j])]
if ch == -1:
outlen = 0
zeroMem(addr outbytes[0], i + 3)
return Base64Status.Incorrect
buffer[j] = cast[byte](ch)
outbytes[k] = cast[byte]((buffer[0] shl 2) or (buffer[1] shr 4))
inc(k)
outbytes[k] = cast[byte]((buffer[1] shl 4) or (buffer[2] shr 2))
inc(k)
outbytes[k] = cast[byte]((buffer[2] shl 6) or buffer[3])
inc(k)
i += 4
if reminder > 0:
if reminder == 1:
outlen = 0
return Base64Status.Incorrect
for j in 0..<reminder:
if (cast[byte](instr[i + j]) and 0x80'u8) != 0:
outlen = 0
return Base64Status.Incorrect
let ch = alphabet.decode[cast[int8](instr[i + j])]
if ch == -1:
outlen = 0
return Base64Status.Incorrect
buffer[j] = cast[byte](ch)
if reminder > 1:
outbytes[k] = cast[byte]((buffer[0] shl 2) or (buffer[1] shr 4))
inc(k)
if reminder > 2:
outbytes[k] = cast[byte]((buffer[1] shl 4) or (buffer[2] shr 2))
inc(k)
outlen = k
result = Base64Status.Success
proc decode*[T: byte|char](btype: typedesc[Base64Types],
instr: openarray[T]): seq[byte] =
## Decode BASE64 string ``instr`` and return sequence of bytes as result.
if len(instr) == 0:
result = newSeq[byte]()
else:
var length = 0
result = newSeq[byte](btype.decodedLength(len(instr)))
if btype.decode(instr, result, length) == Base64Status.Success:
result.setLen(length)
else:
raise newException(Base64Error, "Incorrect base64 string")

View File

@ -10,10 +10,9 @@
## This module implements MultiBase. ## This module implements MultiBase.
## ##
## TODO: ## TODO:
## 1. base64 ## 1. base32z
## 2. base32z
import tables, strutils import tables, strutils
import base32, base58 import base32, base58, base64
type type
MultibaseStatus* {.pure.} = enum MultibaseStatus* {.pure.} = enum
@ -28,7 +27,7 @@ type
outbytes: var openarray[char], outbytes: var openarray[char],
outlen: var int): MultibaseStatus {.nimcall.} outlen: var int): MultibaseStatus {.nimcall.}
MBCodeSize = proc(length: int): int {.nimcall.} MBCodeSize = proc(length: int): int {.nimcall.}
MBCodec = object MBCodec = object
code: char code: char
name: string name: string
@ -108,6 +107,15 @@ proc b58ce(r: Base58Status): MultibaseStatus {.inline.} =
elif r == Base58Status.Success: elif r == Base58Status.Success:
result = MultibaseStatus.Success result = MultibaseStatus.Success
proc b64ce(r: Base64Status): MultibaseStatus {.inline.} =
result = MultiBaseStatus.Error
if r == Base64Status.Incorrect:
result = MultibaseStatus.Incorrect
elif r == Base64Status.Overrun:
result = MultiBaseStatus.Overrun
elif r == Base64Status.Success:
result = MultibaseStatus.Success
proc b32hd(inbytes: openarray[char], proc b32hd(inbytes: openarray[char],
outbytes: var openarray[byte], outbytes: var openarray[byte],
outlen: var int): MultibaseStatus = outlen: var int): MultibaseStatus =
@ -216,6 +224,51 @@ proc b58be(inbytes: openarray[byte],
proc b58el(length: int): int = Base58.encodedLength(length) proc b58el(length: int): int = Base58.encodedLength(length)
proc b58dl(length: int): int = Base58.decodedLength(length) proc b58dl(length: int): int = Base58.decodedLength(length)
proc b64el(length: int): int = Base64.encodedLength(length)
proc b64dl(length: int): int = Base64.decodedLength(length)
proc b64pel(length: int): int = Base64Pad.encodedLength(length)
proc b64pdl(length: int): int = Base64Pad.decodedLength(length)
proc b64e(inbytes: openarray[byte],
outbytes: var openarray[char],
outlen: var int): MultibaseStatus =
result = b64ce(Base64.encode(inbytes, outbytes, outlen))
proc b64d(inbytes: openarray[char],
outbytes: var openarray[byte],
outlen: var int): MultibaseStatus =
result = b64ce(Base64.decode(inbytes, outbytes, outlen))
proc b64pe(inbytes: openarray[byte],
outbytes: var openarray[char],
outlen: var int): MultibaseStatus =
result = b64ce(Base64Pad.encode(inbytes, outbytes, outlen))
proc b64pd(inbytes: openarray[char],
outbytes: var openarray[byte],
outlen: var int): MultibaseStatus =
result = b64ce(Base64Pad.decode(inbytes, outbytes, outlen))
proc b64ue(inbytes: openarray[byte],
outbytes: var openarray[char],
outlen: var int): MultibaseStatus =
result = b64ce(Base64Url.encode(inbytes, outbytes, outlen))
proc b64ud(inbytes: openarray[char],
outbytes: var openarray[byte],
outlen: var int): MultibaseStatus =
result = b64ce(Base64Url.decode(inbytes, outbytes, outlen))
proc b64upe(inbytes: openarray[byte],
outbytes: var openarray[char],
outlen: var int): MultibaseStatus =
result = b64ce(Base64UrlPad.encode(inbytes, outbytes, outlen))
proc b64upd(inbytes: openarray[char],
outbytes: var openarray[byte],
outlen: var int): MultibaseStatus =
result = b64ce(Base64UrlPad.decode(inbytes, outbytes, outlen))
const const
MultibaseCodecs = [ MultibaseCodecs = [
MBCodec(name: "identity", code: chr(0x00), MBCodec(name: "identity", code: chr(0x00),
@ -262,10 +315,18 @@ const
MBCodec(name: "base58btc", code: 'z', MBCodec(name: "base58btc", code: 'z',
decr: b58bd, encr: b58be, decl: b58dl, encl: b58el decr: b58bd, encr: b58be, decl: b58dl, encl: b58el
), ),
MBCodec(name: "base64", code: 'm'), MBCodec(name: "base64", code: 'm',
MBCodec(name: "base64pad", code: 'M'), decr: b64d, encr: b64e, decl: b64dl, encl: b64el
MBCodec(name: "base64url", code: 'u'), ),
MBCodec(name: "base64urlpad", code: 'U') MBCodec(name: "base64pad", code: 'M',
decr: b64pd, encr: b64pe, decl: b64pdl, encl: b64pel
),
MBCodec(name: "base64url", code: 'u',
decr: b64ud, encr: b64ue, decl: b64dl, encl: b64el
),
MBCodec(name: "base64urlpad", code: 'U',
decr: b64upd, encr: b64upe, decl: b64pdl, encl: b64pel
)
] ]
proc initMultiBaseCodeTable(): Table[char, MBCodec] {.compileTime.} = proc initMultiBaseCodeTable(): Table[char, MBCodec] {.compileTime.} =

162
tests/testbase64.nim Normal file
View File

@ -0,0 +1,162 @@
import unittest
import ../libp2p/base64
const TVBasePadding = [
["f", "Zg=="],
["fo", "Zm8="],
["foo", "Zm9v"],
["foob", "Zm9vYg=="],
["fooba", "Zm9vYmE="],
["foobar", "Zm9vYmFy"]
]
const TVBaseNoPadding = [
["f", "Zg"],
["fo", "Zm8"],
["foo", "Zm9v"],
["foob", "Zm9vYg"],
["fooba", "Zm9vYmE"],
["foobar", "Zm9vYmFy"]
]
suite "BASE64 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: int
var e1 = Base64.encode(empty1)
var e2 = Base64Url.encode(empty1)
var e3 = Base64Pad.encode(empty1)
var e4 = Base64UrlPad.encode(empty1)
check:
Base64.encode(empty1, encoded, o1) == Base64Status.Success
Base64Url.encode(empty1, encoded, o2) == Base64Status.Success
Base64Pad.encode(empty1, encoded, o3) == Base64Status.Success
Base64UrlPad.encode(empty1, encoded, o4) == Base64Status.Success
len(e1) == 0
len(e2) == 0
len(e3) == 0
len(e4) == 0
o1 == 0
o2 == 0
o3 == 0
o4 == 0
var d1 = Base64.decode("")
var d2 = Base64Url.decode("")
var d3 = Base64Pad.decode("")
var d4 = Base64UrlPad.decode("")
check:
Base64.decode(empty2, decoded, o1) == Base64Status.Success
Base64Url.decode(empty2, decoded, o2) == Base64Status.Success
Base64Pad.decode(empty2, decoded, o3) == Base64Status.Success
Base64UrlPad.decode(empty2, decoded, o4) == Base64Status.Success
len(d1) == 0
len(d2) == 0
len(d3) == 0
len(d4) == 0
o1 == 0
o2 == 0
o3 == 0
o4 == 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 = Base64.encode(buffer.toOpenArray(0, i))
var b = Base64.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 = Base64.encode(buffer)
var b = Base64.decode(a)
check:
equalMem(addr buffer[0], addr b[0], 256) == true
test "BASE64 padding test vectors":
for item in TVBasePadding:
let plain = cast[seq[byte]](item[0])
let expect = item[1]
var elen = 0
var dlen = 0
var e1 = Base64Pad.encode(plain)
var e2 = newString(Base64Pad.encodedLength(len(plain)))
check:
Base64Pad.encode(plain, e2, elen) == Base64Status.Success
e2.setLen(elen)
check:
e1 == expect
e2 == expect
var d1 = Base64Pad.decode(expect)
var d2 = newSeq[byte](Base64Pad.decodedLength(len(expect)))
check:
Base64Pad.decode(expect, d2, dlen) == Base64Status.Success
d2.setLen(dlen)
check:
d1 == plain
d2 == plain
test "BASE64 no padding test vectors":
for item in TVBaseNoPadding:
let plain = cast[seq[byte]](item[0])
let expect = item[1]
var elen = 0
var dlen = 0
var e1 = Base64.encode(plain)
var e2 = newString(Base64.encodedLength(len(plain)))
check:
Base64.encode(plain, e2, elen) == Base64Status.Success
e2.setLen(elen)
check:
e1 == expect
e2 == expect
var d1 = Base64.decode(expect)
var d2 = newSeq[byte](Base64.decodedLength(len(expect)))
check:
Base64.decode(expect, d2, dlen) == Base64Status.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:
Base64.encode([0'u8], encres, encsize) == Base64Status.Overrun
encsize == Base64.encodedLength(1)
Base64.decode("AA", decres, decsize) == Base64Status.Overrun
decsize == Base64.decodedLength(2)
test "Incorrect test":
var decres = newSeq[byte](10)
var decsize = 0
check:
Base64.decode("A", decres, decsize) == Base64Status.Incorrect
decsize == 0
Base64.decode("AAAAA", decres, decsize) == Base64Status.Incorrect
decsize == 0
Base64.decode("!", decres, decsize) == Base64Status.Incorrect
decsize == 0
Base64.decode("!!", decres, decsize) == Base64Status.Incorrect
decsize == 0
Base64.decode("AA==", decres, decsize) == Base64Status.Incorrect
decsize == 0
Base64.decode("_-", decres, decsize) == Base64Status.Incorrect
decsize == 0
Base64Url.decode("/+", decres, decsize) == Base64Status.Incorrect
decsize == 0

View File

@ -62,26 +62,26 @@ const GoTestVectors = [
"z36UQrhJq9fNDS7DiAHM9YXqDHMPfr4EMArvt", "z36UQrhJq9fNDS7DiAHM9YXqDHMPfr4EMArvt",
"Decentralize everything!!!" "Decentralize everything!!!"
], ],
# [ [
# "base64", "base64",
# "mRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE", "mRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE",
# "Decentralize everything!!!" "Decentralize everything!!!"
# ], ],
# [ [
# "base64url", "base64url",
# "uRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE", "uRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE",
# "Decentralize everything!!!" "Decentralize everything!!!"
# ], ],
# [ [
# "base64pad", "base64pad",
# "MRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE=", "MRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE=",
# "Decentralize everything!!!" "Decentralize everything!!!"
# ], ],
# [ [
# "base64urlpad", "base64urlpad",
# "URGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE=", "URGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE=",
# "Decentralize everything!!!" "Decentralize everything!!!"
# ], ],
] ]
suite "MultiBase test suite": suite "MultiBase test suite":
@ -112,10 +112,10 @@ suite "MultiBase test suite":
MultiBase.encode("base32padupper", plain) == "C" MultiBase.encode("base32padupper", plain) == "C"
MultiBase.encode("base58btc", plain) == "z" MultiBase.encode("base58btc", plain) == "z"
MultiBase.encode("base58flickr", plain) == "Z" MultiBase.encode("base58flickr", plain) == "Z"
# MultiBase.encode("base64", plain) == "m" MultiBase.encode("base64", plain) == "m"
# MultiBase.encode("base64pad", plain) == "M" MultiBase.encode("base64pad", plain) == "M"
# MultiBase.encode("base64url", plain) == "u" MultiBase.encode("base64url", plain) == "u"
# MultiBase.encode("base64urlpad", plain) == "U" MultiBase.encode("base64urlpad", plain) == "U"
check: check:
len(MultiBase.decode("\x00")) == 0 len(MultiBase.decode("\x00")) == 0
# len(MultiBase.decode("1")) == 0 # len(MultiBase.decode("1")) == 0
@ -134,10 +134,10 @@ suite "MultiBase test suite":
len(MultiBase.decode("C")) == 0 len(MultiBase.decode("C")) == 0
len(MultiBase.decode("z")) == 0 len(MultiBase.decode("z")) == 0
len(MultiBase.decode("Z")) == 0 len(MultiBase.decode("Z")) == 0
# len(MultiBase.decode("m")) == 0 len(MultiBase.decode("m")) == 0
# len(MultiBase.decode("M")) == 0 len(MultiBase.decode("M")) == 0
# len(MultiBase.decode("u")) == 0 len(MultiBase.decode("u")) == 0
# len(MultiBase.decode("U")) == 0 len(MultiBase.decode("U")) == 0
check: check:
MultiBase.encode("identity", plain, enc, MultiBase.encode("identity", plain, enc,
olens[0]) == MultiBaseStatus.Success olens[0]) == MultiBaseStatus.Success
@ -243,14 +243,14 @@ suite "MultiBase test suite":
olens[15] == 0 olens[15] == 0
MultiBase.decode("Z", dec, olens[16]) == MultiBaseStatus.Success MultiBase.decode("Z", dec, olens[16]) == MultiBaseStatus.Success
olens[16] == 0 olens[16] == 0
# MultiBase.decode("m", dec, olens[16]) == MultiBaseStatus.Success MultiBase.decode("m", dec, olens[16]) == MultiBaseStatus.Success
# olens[16] == 0 olens[16] == 0
# MultiBase.decode("M", dec, olens[16]) == MultiBaseStatus.Success MultiBase.decode("M", dec, olens[16]) == MultiBaseStatus.Success
# olens[16] == 0 olens[16] == 0
# MultiBase.decode("u", dec, olens[16]) == MultiBaseStatus.Success MultiBase.decode("u", dec, olens[16]) == MultiBaseStatus.Success
# olens[16] == 0 olens[16] == 0
# MultiBase.decode("U", dec, olens[16]) == MultiBaseStatus.Success MultiBase.decode("U", dec, olens[16]) == MultiBaseStatus.Success
# olens[16] == 0 olens[16] == 0
test "go-multibase test vectors": test "go-multibase test vectors":
for item in GoTestVectors: for item in GoTestVectors:
let encoding = item[0] let encoding = item[0]