Skip to content

Commit 8f68fce

Browse files
committed
Add base36 implementation
1 parent 5d9539e commit 8f68fce

3 files changed

Lines changed: 49 additions & 0 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.ipfs.multibase;
2+
3+
import java.math.*;
4+
5+
public class Base36 {
6+
7+
public static byte[] decode(String in) {
8+
byte[] withoutLeadingZeroes = new BigInteger(in, 36).toByteArray();
9+
int zeroPrefixLength = zeroPrefixLength(in);
10+
byte[] res = new byte[zeroPrefixLength + withoutLeadingZeroes.length];
11+
System.arraycopy(withoutLeadingZeroes, 0, res, zeroPrefixLength, withoutLeadingZeroes.length);
12+
return res;
13+
}
14+
15+
public static String encode(byte[] in) {
16+
String withoutLeadingZeroes = new BigInteger(1, in).toString(36);
17+
int zeroPrefixLength = zeroPrefixLength(in);
18+
StringBuilder b = new StringBuilder();
19+
for (int i=0; i < zeroPrefixLength; i++)
20+
b.append("0");
21+
b.append(withoutLeadingZeroes);
22+
return b.toString();
23+
}
24+
25+
private static int zeroPrefixLength(byte[] bytes) {
26+
for (int i = 0; i < bytes.length; i++) {
27+
if (bytes[i] != 0) {
28+
return i;
29+
}
30+
}
31+
return bytes.length;
32+
}
33+
34+
private static int zeroPrefixLength(String in) {
35+
for (int i = 0; i < in.length(); i++) {
36+
if (in.charAt(i) != '0') {
37+
return i;
38+
}
39+
}
40+
return in.length();
41+
}
42+
}

src/main/java/io/ipfs/multibase/Multibase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public enum Base {
1717
Base32Upper('B'),
1818
Base32Hex('v'),
1919
Base32HexUpper('V'),
20+
Base36('k'),
2021
Base58Flickr('Z'),
2122
Base58BTC('z'),
2223
Base64('m'),
@@ -55,6 +56,8 @@ public static String encode(Base b, byte[] data) {
5556
return b.prefix + new String(new Base32(true).encode(data)).toLowerCase().replaceAll("=", "");
5657
case Base32HexUpper:
5758
return b.prefix + new String(new Base32(true).encode(data)).replaceAll("=", "");
59+
case Base36:
60+
return b.prefix + Base36.encode(data);
5861
case Base64:
5962
return b.prefix + Base64.encodeBase64String(data).replaceAll("=", "");
6063
case Base64Pad:
@@ -84,6 +87,8 @@ public static byte[] decode(String data) {
8487
return new Base32(true).decode(rest);
8588
case Base32HexUpper:
8689
return new Base32(true).decode(rest.toLowerCase());
90+
case Base36:
91+
return Base36.decode(rest);
8792
case Base64Pad:
8893
case Base64:
8994
return Base64.decodeBase64(rest);

src/test/java/io/ipfs/multibase/MultibaseTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public static Collection<Object[]> data() {
4848
{Multibase.Base.Base32Upper, hexToBytes("446563656e7472616c697a652065766572797468696e67212121"), "BIRSWGZLOORZGC3DJPJSSAZLWMVZHS5DINFXGOIJBEE"},
4949
{Multibase.Base.Base32Hex, hexToBytes("446563656e7472616c697a652065766572797468696e67212121"), "v8him6pbeehp62r39f9ii0pbmclp7it38d5n6e89144"},
5050
{Multibase.Base.Base32HexUpper, hexToBytes("446563656e7472616c697a652065766572797468696e67212121"), "V8HIM6PBEEHP62R39F9II0PBMCLP7IT38D5N6E89144"},
51+
{Multibase.Base.Base36, hexToBytes("446563656e7472616c697a652065766572797468696e67212121"), "km552ng4dabi4neu1oo8l4i5mndwmpc3mkukwtxy9"},
52+
{Multibase.Base.Base36, hexToBytes("00446563656e7472616c697a652065766572797468696e67212121"), "k0m552ng4dabi4neu1oo8l4i5mndwmpc3mkukwtxy9"},
5153
{Multibase.Base.Base58BTC, hexToBytes("446563656e7472616c697a652065766572797468696e67212121"), "z36UQrhJq9fNDS7DiAHM9YXqDHMPfr4EMArvt"},
5254
{Multibase.Base.Base64, hexToBytes("446563656e7472616c697a652065766572797468696e67212121"), "mRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE"},
5355
{Multibase.Base.Base64Pad, hexToBytes("446563656e7472616c697a652065766572797468696e67212121"), "MRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE="},

0 commit comments

Comments
 (0)