multiformats/java-multibase

Base32, Base64 are not RFC4648 compliance!

Closed this issue · 4 comments

According to RFC4648

  • Base 32 Encoding is based on 5-bit group
  • Base 64 Encoding is based on 6-bit group

However, the implementations of Base 32 and Base 64 in this project is as same as Base58, which is not correct.

This is also conflict with the specs stated here multiformats/multibase:

encoding      codes   name
identity      0x00    8-bit binary (encoder and decoder keeps data unmodified)
base1         1       unary tends to be 11111
base2         0       binary has 1 and 0
base8         7       highest char in octal
base10        9       highest char in decimal
base16        F, f    highest char in hex
base32        B, b    rfc4648 - no padding - highest letter
base32pad     C, c    rfc4648 - with padding
base32hex     V, v    rfc4648 - no padding - highest char
base32hexpad  T, t    rfc4648 - with padding
base32z       h       z-base-32 - used by Tahoe-LAFS - highest letter
base58flickr  Z       highest char
base58btc     z       highest char
base64        m       rfc4648 - no padding
base64pad     M       rfc4648 - with padding - MIME encoding
base64url     u       rfc4648 - no padding
base64urlpad  U       rfc4648 - with padding

FYI: If you want something probably more accurate (or to get inspirations to fix from):
https://github.com/m-m-m/binary/tree/master/src/main/java/net/sf/mmm/binary/api/codec

They do use 5 and 6 bit groups. Can you give an example where the encoding is incorrect?

I can confirm that Base32 is broken, Base32 indeed should be using 5bit groups. Had to swap Base32 implementation for Apache codec to get CID working.... here is example of CID that is Base32 encoded but fails baegbeibondkkrhxfprzwrlgxxltavqhweh2ylhu4hgo5lxjxpqbpfsw2lu.

Here is simple jUnit test (b being left out of the string)

   @Test
   void testBase32() {
      String base = "aegbeibondkkrhxfprzwrlgxxltavqhweh2ylhu4hgo5lxjxpqbpfsw2lu";
      byte[] multibaseBytes = io.ipfs.multibase.Base32.decode(base);
      byte[] apacheBytes = new org.apache.commons.codec.binary.Base32().decode(base);
      assertArrayEquals(apacheBytes, multibaseBytes);
   }

That test fails and it is not because Apache got it wrong :)

This is now fixed in master. Thank you.