Skip to content

Commit

Permalink
Merge pull request #10 from chalkers/master
Browse files Browse the repository at this point in the history
Updated code to allow custom character set
  • Loading branch information
andrew committed Feb 23, 2015
2 parents b4b6783 + a8e70c6 commit a89d2a5
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 31 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ node_modules
npm-debug.log

build
.lock-wscript
.lock-wscript

.idea
15 changes: 15 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,27 @@ npm install base62

## Usage

### Default Character Set Example

```javascript
Base62 = require('base62')
Base62.encode(999) // 'g7'
Base62.decode('g7') // 999
```

### Custom Character Set Example

The default character set is `0-9a-zA-Z`. This can be updated to a custom character set. Naturally, it must be 62 characters long.

Instead of the character set `0-9a-zA-Z` you want to use `0-9A-Za-z`, call the `setCharacterSet()` method on the Base62 object passing in the string `"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"`. Note that all characters must be unique.

```javascript
Base62 = require('base62')
Base62.setCharacterSet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
Base62.encode(999) // 'G7'
Base62.decode('G7') // 999
```

## Development

Source hosted at [GitHub](http://github.com/andrew/base62.js).
Expand Down
61 changes: 37 additions & 24 deletions base62.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
module.exports = (function (my) {
my.chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

my.encode = function(i){
if (i === 0) {return '0';}
var s = '';
while (i > 0) {
s = this.chars[i % 62] + s;
i = Math.floor(i/62);
}
return s;
};
my.decode = function(a,b,c,d){
for (
b = c = (
a === (/\W|_|^$/.test(a += "") || a)
) - 1;
d = a.charCodeAt(c++);
)
b = b * 62 + d - [, 48, 29, 87][d >> 5];
return b;
};

return my;
module.exports = (function (Base62) {
var DEFAULT_CHARACTER_SET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

Base62.encode = function(integer){
if (integer === 0) {return '0';}
var s = '';
while (integer > 0) {
s = Base62.characterSet[integer % 62] + s;
integer = Math.floor(integer/62);
}
return s;
};

Base62.decode = function(base62String){
var val = 0, base62Chars = base62String.split("").reverse();
base62Chars.forEach(function(character, index){
val += Base62.characterSet.indexOf(character) * Math.pow(62, index);
});
return val;
};

Base62.setCharacterSet = function(chars) {
var arrayOfChars = chars.split(""), uniqueCharacters = [];

if(arrayOfChars.length != 62) throw Error("You must supply 62 characters");

arrayOfChars.forEach(function(char){
if(!~uniqueCharacters.indexOf(char)) uniqueCharacters.push(char);
});

if(uniqueCharacters.length != 62) throw Error("You must use unique characters.");

Base62.characterSet = arrayOfChars;
};

Base62.setCharacterSet(DEFAULT_CHARACTER_SET);
return Base62;
}({}));
72 changes: 66 additions & 6 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,73 @@ var assert = require('assert');
var Base62 = require('../base62');

describe("encode", function() {
it("should encode a number to a Base62 string", function() {
assert.equal(Base62.encode(999), 'g7');
});
it("should encode a number to a Base62 string", function() {
assert.equal(Base62.encode(999), 'g7');
assert.equal(Base62.encode(65), '13');
//test big numbers
assert.equal(Base62.encode(10000000000001), "2Q3rKTOF");
assert.equal(Base62.encode(10000000000002), "2Q3rKTOG");

});
});

describe("decode", function() {
it("should decode a number from a Base62 string", function() {
assert.equal(Base62.decode('g7'), 999);
});
it("should decode a number from a Base62 string", function() {
assert.equal(Base62.decode('g7'), 999);
assert.equal(Base62.decode('13'), 65);
//test big numbers
assert.equal(Base62.decode("2Q3rKTOF"), 10000000000001);
assert.equal(Base62.decode("2Q3rKTOH"), 10000000000003);
});
});

describe("setCharacterSequence", function(){
it("should update the character sequence", function(){
Base62.setCharacterSet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");

//Test default character set is not intact
assert.notEqual(Base62.encode(999), 'g7');

//Test new character set test cases
var testCases = {
"G7": 999,
"Lxf7": 5234233,
"qx": 3283,
"29": 133,
"1S": 90,
"3k": 232,
"4I": 266,
"2X": 157,
"1E": 76,
"1L": 83
};

Object.keys(testCases).forEach(function(base62String){
assert.equal(Base62.encode(testCases[base62String]), base62String);
assert.equal(Base62.decode(base62String), testCases[base62String]);
});

});

it("should throw exceptions on invalid strings", function(){
var errorCheck = function(err) {
if ( (err instanceof Error) && /value/.test(err) ) {
return true;
}
};

assert.throws(function(){
Base62.setCharacterSet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy");
}, /You must supply 62 characters/);

assert.throws(function(){
Base62.setCharacterSet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;");
}, /You must supply 62 characters/);


assert.throws(function(){
Base62.setCharacterSet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxzz");
}, /You must use unique characters/);

});
});

0 comments on commit a89d2a5

Please sign in to comment.