twonly-app-dependencies/hashlib_codecs/test/base32_test.dart
2025-12-07 16:10:41 +01:00

457 lines
16 KiB
Dart

import 'package:base32/base32.dart' as base32;
import 'package:base32/encodings.dart';
import 'package:base_codecs/base_codecs.dart' as base_codecs;
import 'package:hashlib_codecs/hashlib_codecs.dart';
import 'package:test/test.dart';
import './utils.dart';
void main() {
group('Test base32', () {
// source: https://github.com/daegalus/dart-base32
test('parameter overrides', () {
var s = 'foobar';
var r = 'MZXW6YTBOI======';
var np = 'MZXW6YTBOI';
var a = toBase32(s.codeUnits);
expect(a, equals(r));
a = toBase32(
s.codeUnits,
codec: Base32Codec.standard,
padding: false,
);
expect(a, equals(np));
a = toBase32(
s.codeUnits,
codec: Base32Codec.standard,
lower: true,
);
expect(a, equals(r));
a = toBase32(
s.codeUnits,
codec: Base32Codec.standard,
padding: false,
lower: true,
);
expect(a, equals(np));
});
group('encoding <-> decoding', () {
test('standard', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b);
expect(r.toUpperCase(), equals(r), reason: 'length $i');
var a = fromBase32(r);
expect(a, equals(b), reason: 'length $i');
}
});
test('lowercase', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, lower: true);
expect(r.toLowerCase(), equals(r), reason: 'length $i');
var a = fromBase32(r);
expect(a, equals(b), reason: 'length $i');
}
});
test('standard no padding', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, padding: false);
expect(r.toUpperCase(), equals(r), reason: 'length $i');
expect(r, isNot(endsWith('=')), reason: 'length $i');
var a = fromBase32(r);
expect(a, equals(b), reason: 'length $i');
}
});
test('hex uppercase', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.hex);
var a = fromBase32(r, codec: Base32Codec.hex);
expect(a, equals(b), reason: 'length $i');
}
});
test('hex lowercase', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.hexLower);
var a = fromBase32(r, codec: Base32Codec.hexLower);
expect(a, equals(b), reason: 'length $i');
}
});
test('crockford', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.crockford);
expect(r, isNot(endsWith('=')), reason: 'length $i');
var a = fromBase32(r, codec: Base32Codec.crockford);
expect(a, equals(b), reason: 'length $i');
}
});
test('geohash', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.geohash);
expect(r.toLowerCase(), equals(r), reason: 'length $i');
var a = fromBase32(r, codec: Base32Codec.geohash);
expect(a, equals(b), reason: 'length $i');
}
});
test('geohash no padding', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.geohash, padding: false);
expect(r, isNot(endsWith('=')), reason: 'length $i');
var a = fromBase32(r, codec: Base32Codec.geohash);
expect(a, equals(b), reason: 'length $i');
}
});
test('word-safe', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.wordSafe);
var a = fromBase32(r, codec: Base32Codec.wordSafe);
expect(a, equals(b), reason: 'length $i');
}
});
test('word-safe no padding', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.wordSafe, padding: false);
expect(r, isNot(endsWith('=')), reason: 'length $i');
var a = fromBase32(r, codec: Base32Codec.wordSafe);
expect(a, equals(b), reason: 'length $i');
}
});
test('z-base-32', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var r = toBase32(b, codec: Base32Codec.z);
expect(r, isNot(endsWith('=')), reason: 'length $i');
var a = fromBase32(r, codec: Base32Codec.z);
expect(a, equals(b), reason: 'length $i');
}
});
});
group('encoding', () {
group('no padding', () {
test('"" -> ""', () {
var s = '';
var a = toBase32(s.codeUnits, padding: false);
expect(a, equals(''));
});
test('f -> MY', () {
var s = 'f';
var a = toBase32(s.codeUnits, padding: false);
expect(a, equals('MY'));
});
test('fo -> MZXQ', () {
var s = 'fo';
var a = toBase32(s.codeUnits, padding: false);
expect(a, equals('MZXQ'));
});
test('foo -> MZXW6', () {
var s = 'foo';
var a = toBase32(s.codeUnits, padding: false);
expect(a, equals('MZXW6'));
});
test('foob -> MZXW6YQ', () {
var s = 'foob';
var a = toBase32(s.codeUnits, padding: false);
expect(a, equals('MZXW6YQ'));
});
test('fooba -> MZXW6YTB', () {
var s = 'fooba';
var a = toBase32(s.codeUnits, padding: false);
expect(a, equals('MZXW6YTB'));
});
test('foobar -> MZXW6YTBOI', () {
var s = 'foobar';
var a = toBase32(s.codeUnits, padding: false);
expect(a, equals('MZXW6YTBOI'));
});
test('[0, 0, 0] => AAAAA', () {
var inp = [0, 0, 0];
var out = "AAAAA";
var act = toBase32(inp, padding: false);
expect(act, equals(out));
});
test('48656c6c6f21deadbeef -> JBSWY3DPEHPK3PXP', () {
var encoded = fromHex('48656c6c6f21deadbeef');
var actual = toBase32(encoded, padding: false);
expect(actual, equals('JBSWY3DPEHPK3PXP'));
});
test('48656c6c6f21deadbe -> JBSWY3DPEHPK3PQ', () {
var encoded = fromHex('48656c6c6f21deadbe');
var actual = toBase32(encoded, padding: false);
expect(actual, equals('JBSWY3DPEHPK3PQ'));
});
test('foobar --lower--> mzxw6ytboi', () {
var text = 'foobar';
var actual = toBase32(text.codeUnits, padding: false, lower: true);
expect(actual, equals('mzxw6ytboi'));
});
test('48656c6c6f21deadbeef --lower--> jbswy3dpehpk3pxp', () {
var text = fromHex('48656c6c6f21deadbeef');
var actual = toBase32(text, padding: false, lower: true);
expect(actual, equals('jbswy3dpehpk3pxp'));
});
});
group('with padding', () {
test('f -> MY======', () {
var s = 'f';
var r = 'MY======';
expect(toBase32(s.codeUnits), equals(r));
});
test('fo -> MZXQ====', () {
var s = 'fo';
var r = 'MZXQ====';
expect(toBase32(s.codeUnits), equals(r));
});
test('foo -> MZXW6===', () {
var s = 'foo';
var r = 'MZXW6===';
expect(toBase32(s.codeUnits), equals(r));
});
test('foob -> MZXW6YQ=', () {
var s = 'foob';
var r = 'MZXW6YQ=';
expect(toBase32(s.codeUnits), equals(r));
});
test('foobar -> MZXW6YTBOI======', () {
var s = 'foobar';
var r = 'MZXW6YTBOI======';
expect(toBase32(s.codeUnits), equals(r));
});
test('48656c6c6f21deadbe -> JBSWY3DPEHPK3PQ=', () {
var s = String.fromCharCodes(fromHex('48656c6c6f21deadbe'));
var r = 'JBSWY3DPEHPK3PQ=';
expect(toBase32(s.codeUnits), equals(r));
});
test('[0, 0, 0] => AAAAA===', () {
var inp = [0, 0, 0];
var out = "AAAAA===";
expect(toBase32(inp), equals(out));
});
});
});
group('decoding', () {
group('no padding', () {
test('"" -> ""', () {
var s = '';
expect(fromBase32(''), equals(s.codeUnits));
});
test('MY -> f', () {
var s = 'f';
expect(fromBase32('MY'), equals(s.codeUnits));
});
test('MZXQ -> fo', () {
var s = 'fo';
expect(fromBase32('MZXQ'), equals(s.codeUnits));
});
test('MZXW6 -> foo', () {
var s = 'foo';
expect(fromBase32('MZXW6'), equals(s.codeUnits));
});
test('MZXW6YQ -> foob', () {
var s = 'foob';
expect(fromBase32('MZXW6YQ'), equals(s.codeUnits));
});
test('MZXW6YTB -> fooba', () {
var s = 'fooba';
expect(fromBase32('MZXW6YTB'), equals(s.codeUnits));
});
test('MZXW6YTBOI -> foobar', () {
var s = 'foobar';
expect(fromBase32('MZXW6YTBOI'), equals(s.codeUnits));
});
test('JBSWY3DPEHPK3PXP -> 48656c6c6f21deadbeef', () {
var decoded = fromBase32('JBSWY3DPEHPK3PXP');
expect(toHex(decoded), equals('48656c6c6f21deadbeef'));
});
test('JBSWY3DPEHPK3PQ -> 48656c6c6f21deadbe', () {
var decoded = fromBase32('JBSWY3DPEHPK3PQ');
expect(toHex(decoded), equals('48656c6c6f21deadbe'));
});
test('mzxw6ytboi -> foobar', () {
var s = 'foobar';
expect(fromBase32('mzxw6ytboi'), equals(s.codeUnits));
});
test('jbswy3dpehpk3pxp -> 48656c6c6f21deadbeef', () {
var decoded = fromBase32('jbswy3dpehpk3pxp');
expect(toHex(decoded), equals('48656c6c6f21deadbeef'));
});
test('jbswy3dpehpk3pq -> 48656c6c6f21deadbe', () {
var decoded = fromBase32('jbswy3dpehpk3pq');
expect(toHex(decoded), equals('48656c6c6f21deadbe'));
});
});
group('with padding', () {
test('MY====== -> f', () {
var s = 'MY======';
var r = 'f';
expect(fromBase32(s), equals(r.codeUnits));
});
test('MZXQ==== -> fo', () {
var s = 'MZXQ====';
var r = 'fo';
expect(fromBase32(s), equals(r.codeUnits));
});
test('MZXW6=== -> foo', () {
var s = 'MZXW6===';
var r = 'foo';
expect(fromBase32(s), equals(r.codeUnits));
});
test('MZXW6YQ= -> foob', () {
var s = 'MZXW6YQ=';
var r = 'foob';
expect(fromBase32(s), equals(r.codeUnits));
});
test('MZXW6YTBOI====== -> foobar', () {
var s = 'MZXW6YTBOI======';
var r = 'foobar';
expect(fromBase32(s), equals(r.codeUnits));
});
test('JBSWY3DPEHPK3PQ= -> 48656c6c6f21deadbe', () {
var s = 'JBSWY3DPEHPK3PQ=';
var r = String.fromCharCodes(fromHex('48656c6c6f21deadbe'));
expect(fromBase32(s), equals(r.codeUnits));
});
test('AAAA => [0, 0, 0]', () {
var inp = [0, 0, 0];
var out = "AAAAA===";
expect(fromBase32(out), equals(inp));
});
});
group(' with invalid chars', () {
test('"Error!"', () {
expect(() => fromBase32("Error!"), throwsFormatException);
});
test('"-10"', () {
expect(() => fromBase32("-10"), throwsFormatException);
});
test('"s*mething"', () {
expect(() => fromBase32("s*mething"), throwsFormatException);
});
});
group('with invalid length', () {
test('"1"', () {
expect(() => fromBase32("1"), throwsFormatException);
});
test('"12"', () {
expect(() => fromBase32("12"), throwsFormatException);
});
test('"123"', () {
expect(() => fromBase32("123"), throwsFormatException);
});
test('"1234"', () {
expect(() => fromBase32("1234"), throwsFormatException);
});
test('"12345"', () {
expect(() => fromBase32("12345"), throwsFormatException);
});
test('"123456"', () {
expect(() => fromBase32("123456"), throwsFormatException);
});
test('"1234567"', () {
expect(() => fromBase32("1234567"), throwsFormatException);
});
test('"123456789"', () {
expect(() => fromBase32("123456789"), throwsFormatException);
});
test('"1234567890"', () {
expect(() => fromBase32("1234567890"), throwsFormatException);
});
test('"12345678901"', () {
expect(() => fromBase32("12345678901"), throwsFormatException);
});
test('"123456789012"', () {
expect(() => fromBase32("123456789012"), throwsFormatException);
});
test('"1234567890123"', () {
expect(() => fromBase32("1234567890123"), throwsFormatException);
});
test('"12345678901234"', () {
expect(() => fromBase32("12345678901234"), throwsFormatException);
});
test('"123456789012345"', () {
expect(() => fromBase32("123456789012345"), throwsFormatException);
});
});
});
group('compare against package: base_codecs', () {
test('encoding', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var hashlib = toBase32(b);
var other = base_codecs.base32RfcEncode(b);
expect(hashlib, other, reason: 'length $i');
}
});
test('decoding (uppercase)', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var h = toBase32(b);
var hashlib = fromBase32(h);
var other = base_codecs.base32RfcDecode(h);
expect(hashlib, other, reason: 'length $i');
}
});
test('decoding (lowercase)', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var h = toBase32(b, lower: true);
var hashlib = fromBase32(h);
var other = base_codecs.base32RfcDecode(h);
expect(hashlib, other, reason: 'length $i');
}
});
});
group('compare against package: base32', () {
test('encoding (uppercase)', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var hashlib = toBase32(b);
var other = base32.base32.encodeString(String.fromCharCodes(b));
expect(hashlib, other, reason: 'length $i');
}
});
test('encoding (lowercase)', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var hashlib = toBase32(b, lower: true);
var other = base32.base32.encodeString(String.fromCharCodes(b),
encoding: Encoding.nonStandardRFC4648Lower);
expect(hashlib, other, reason: 'length $i');
}
});
test('decoding (uppercase)', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var h = toBase32(b);
var hashlib = fromBase32(h);
var other = base32.base32.decode(h);
expect(hashlib, other, reason: 'length $i');
}
});
test('decoding (lowercase)', () {
for (int i = 0; i < 100; ++i) {
var b = randomBytes(i);
var h = toBase32(b, lower: true);
var hashlib = fromBase32(h);
var other = base32.base32.decode(
h,
encoding: Encoding.nonStandardRFC4648Lower,
);
expect(hashlib, other, reason: 'length $i');
}
});
});
});
}