Recently, I was as surprised as you will no doubt be, to discover that there didn’t seem to be a Base32 encoder for JavaScript! There are lots of Base64 encoders out there (and just as many for Hexadecimal), but Base32 seems to be a pretty small niche.
So I decided to write my own, and about half-way through, it evolved from a Base32 encoder to a multi-base encoder: Nibbler.js.
An important note: Base32, Base64, etc. are not encryption. They are content-encoding schemes that simply re-group the binary digits of your data into smaller bundles, so that any data can be transmitted as plain ASCII. See the Wikipedia article about Base64 for more info.
Usage
Nibbler itself isn’t the encoder object, but rather a constructor for easily creating encoders. Base32 carries five bits per byte, so to create a Base32 encoder object, set the codeBits
option to 5
.
base32 = new Nibbler({
dataBits: 8,
codeBits: 5,
keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
pad: '='
});
The object has encode and decode methods:
base32.encode("Hello, World"); // "JBSWY3DPFQQFO33SNRSCC====="
base32.decode("IFWG62DB"); // "Aloha"
Base64 carries 6 bits per byte:
base64 = new Nibbler({
dataBits: 8,
codeBits: 6,
keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
pad: '='
});
If the data you’re encoding only uses seven bits, you can create an object that excludes those unused bits from its encoded output, by setting the dataBits
option to 7
:
base64_7bit = new Nibbler({
dataBits: 7,
codeBits: 6,
keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
pad: '='
});
In the next few days or years I plan to create an encode/decode tool to provide a user interface to this library.
12 Responses
Great code, was looking for something like this, thanks.
I did add a UTF8_encode so it match the PHP base64 decode, else there where no way it would take ñ or ó ...
chears!
Jacob
Hey, I adapted this to work nicely with Nodejs. :)
https://github.com/mattrobenolt/node_nibbler
Thanks for sharing!
Thanks for the code, but I can't decode it with c#;
error message says "Invalid character in a Base-64 string." your script coded "3226,3222,3217" to "MzIyNiwzMjIyLDMyMTc===" but c# can't decode it, whats the problem?
Hi, Farhad, sorry it took me this long to answer, but I didn't see that I had a comment until last night.
I've never used c# before, but my best guess is that it doesn't know what to do with the padding character, "=". Have you tried removing those to see what it does?
Great code, have converted this to C# :)
@Farhad
The reason C#'s Base64 methods don't decode Base64
strings encoded with Nibbler, is due to Nibbler
adding to much padding on certain input strings.
In your case Nibbler added 2 extra padding chars.
"3226,3222,3217" should be "MzIyNiwzMjIyLDMyMTc="
@Ej52, thanks for spotting this. I probably won't have time to look for the bug soon, but if no one (it could be you!) submits a fix before I get to it, it's on my list!
@Thomas, temp fix based on the size of the "keyString"
not great but produces the right amount of padding
for Base64 encoding ;)
len = output.length % group;
if (keyString.length == 64)
len = 3 - (input.length % 3);
for (i = 0; i < len; i += 1) {
output.push(pad);
}
@Thomas, after trying multiple math equations to get the
padding correct based on the "dataBits" and "codeBits" it
seems there is no way to do it.
The only way to get the padding correct is to work out the
quantum's seprately based on the encoding (64/32).
Padding issue aside, Nibbler seems to work perfectly for
base 64, 32, 16(HEX).
A year and a half later... fixed! It was really simple once I managed to remember that this needed fixing, at a time when I had the time to do it.
I fixed it by replacing wrong math...
...with right math:
I followed the example here and I can't comment there so maybe you can help
http://blog.thomassmart.com/2012/08/security-tips-1/
Some times it works and some times it doesn't. I made a fiddle so you can try it.
http://jsfiddle.net/En7m5/3/
Nibbler only works all the time if I use the key you used in your example ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 which is less secure because it isn't randomized. I tried adding padding but that didn't work and I tried other random keys besides the one in the example and those don't work all the time either.
Gene, the reason the example in your Fiddle doesn't work is that the key "JNUBDWRZALTX10FMM9EO3628CKKP5IVY7S" has duplicate characters. At a glance I notice two M's and two K's. Simply put, when Nibbler (or any base32 library) decodes "06M8DKK9ZDPOF" and finds an M, it has no way of knowing which M in the keyString it's supposed to be, and so it uses the first one it finds. Same for the K's. Any 32 unique ASCII characters, in any order, will be a suitable keyString for Base32. For Base64, any 64. Any duplicate characters in the keyString, even if they're not consecutive the way they are in the example, will wreck the whole thing.
However, unrelated to this problem, the thomassmart.com usage is completely wrong. Base32, Base64, etc. should *never* be used as encryption. These encodings are nothing more than a way of representing data in a format that can be transmitted as plain ASCII text. It's no good for keeping secrets.