Last active
December 11, 2015 21:38
-
-
Save kmlx/4663311 to your computer and use it in GitHub Desktop.
All credits go out to: http://www.experts-exchange.com/Programming/System/Windows__Programming/A_3216-Fast-Base64-Encode-and-Decode.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Author: Radu Apostoleanu | |
E-mail: radu.apostoleanu@gmail.com | |
Description: | |
This is a nodeJs module for fast base64 encoding based on this link: | |
http://www.experts-exchange.com/Programming/System/Windows__Programming/A_3216-Fast-Base64-Encode-and-Decode.html | |
The code was made for Linux environment from Windows example. | |
*/ | |
#include <node.h> | |
#include <v8.h> | |
#include <assert.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
//Defining some common windows' types. They must match the byte length for this to be effective. | |
typedef short int WORD; | |
typedef unsigned int DWORD; | |
using namespace v8; | |
//Defining static information tables | |
static char Base64Digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
static WORD* Base64Digits8192 = (WORD*) "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cIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZcacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczc0c1c2c3c4c5c6c7c8c9c+c/dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZdadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd0d1d2d3d4d5d6d7d8d9d+d/eAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZeaebecedeeefegeheiejekelemeneoepeqereseteuevewexeyeze0e1e2e3e4e5e6e7e8e9e+e/fAfBfCfDfEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZfafbfcfdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzf0f1f2f3f4f5f6f7f8f9f+f/gAgBgCgDgEgFgGgHgIgJgKgLgMgNgOgPgQgRgSgTgUgVgWgXgYgZgagbgcgdgegfggghgigjgkglgmgngogpgqgrgsgtgugvgwgxgygzg0g1g2g3g4g5g6g7g8g9g+g/hAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWhXhYhZhahbhchdhehfhghhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzh0h1h2h3h4h5h6h7h8h9h+h/iAiBiCiDiEiFiGiHiIiJiKiLiMiNiOiPiQiRiSiTiUiViWiXiYiZiaibicidieifigihiiijikiliminioipiqirisitiuiviwixiyizi0i1i2i3i4i5i6i7i8i9i+i/jAjBjCjDjEjFjGjHjIjJjKjLjMjNjOjPjQjRjSjTjUjVjWjXjYjZjajbjcjdjejfjgjhjijjjkjljmjnjojpjqjrjsjtjujvjwjxjyjzj0j1j2j3j4j5j6j7j8j9j+j/kAkBkCkDkEkFkGkHkIkJkKkLkMkNkOkPkQkRkSkTkUkVkWkXkYkZkakbkckdkekfkgkhkikjkkklkmknkokpkqkrksktkukvkwkxkykzk0k1k2k3k4k5k6k7k8k9k+k/lAlBlClDlElFlGlHlIlJlKlLlMlNlOlPlQlRlSlTlUlVlWlXlYlZlalblcldlelflglhliljlklllmlnlolplqlrlsltlulvlwlxlylzl0l1l2l3l4l5l6l7l8l9l+l/mAmBmCmDmEmFmGmHmImJmKmLmMmNmOmPmQmRmSmTmUmVmWmXmYmZmambmcmdmemfmgmhmimjmkmlmmmnmompmqmrmsmtmumvmwmxmymzm0m1m2m3m4m5m6m7m8m9m+m/nAnBnCnDnEnFnGnHnInJnKnLnMnNnOnPnQnRnSnTnUnVnWnXnYnZnanbncndnenfngnhninjnknlnmnnnonpnqnrnsntnunvnwnxnynzn0n1n2n3n4n5n6n7n8n9n+n/oAoBoCoDoEoFoGoHoIoJoKoLoMoNoOoPoQoRoSoToUoVoWoXoYoZoaobocodoeofogohoiojokolomonooopoqorosotouovowoxoyozo0o1o2o3o4o5o6o7o8o9o+o/pApBpCpDpEpFpGpHpIpJpKpLpMpNpOpPpQpRpSpTpUpVpWpXpYpZpapbpcpdpepfpgphpipjpkplpmpnpopppqprpsptpupvpwpxpypzp0p1p2p3p4p5p6p7p8p9p+p/qAqBqCqDqEqFqGqHqIqJqKqLqMqNqOqPqQqRqSqTqUqVqWqXqYqZqaqbqcqdqeqfqgqhqiqjqkqlqmqnqoqpqqqrqsqtquqvqwqxqyqzq0q1q2q3q4q5q6q7q8q9q+q/rArBrCrDrErFrGrHrIrJrKrLrMrNrOrPrQrRrSrTrUrVrWrXrYrZrarbrcrdrerfrgrhrirjrkrlrmrnrorprqrrrsrtrurvrwrxryrzr0r1r2r3r4r5r6r7r8r9r+r/sAsBsCsDsEsFsGsHsIsJsKsLsMsNsOsPsQsRsSsTsUsVsWsXsYsZsasbscsdsesfsgshsisjskslsmsnsospsqsrssstsusvswsxsyszs0s1s2s3s4s5s6s7s8s9s+s/tAtBtCtDtEtFtGtHtItJtKtLtMtNtOtPtQtRtStTtUtVtWtXtYtZtatbtctdtetftgthtitjtktltmtntotptqtrtstttutvtwtxtytzt0t1t2t3t4t5t6t7t8t9t+t/uAuBuCuDuEuFuGuHuIuJuKuLuMuNuOuPuQuRuSuTuUuVuWuXuYuZuaubucudueufuguhuiujukulumunuoupuqurusutuuuvuwuxuyuzu0u1u2u3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"; | |
char* ToCString( v8::String::Utf8Value& value) { | |
return *value ; | |
} | |
Handle<Value > Method(const Arguments& args){ | |
HandleScope scope; | |
//CONVERT VALUES | |
v8::String::Utf8Value str(args[0]); | |
char* pSrc = ToCString(str); | |
int nLenSrc = strlen(pSrc); | |
//Calculation of output length | |
int nLenOut= ((nLenSrc+2)/3)*4+1; // 4 out for every 3 in, rounded up | |
//memory allocation and initialization | |
char* pDst = (char*) malloc(nLenOut*sizeof(WORD)); | |
char* p = pDst; | |
memset(p,0,nLenOut*2); | |
//the algorithm in the paper mentioned at the begining | |
while( nLenSrc > 2 ) { | |
DWORD n= pSrc[0]; // xxx1 | |
n <<= 8; // xx1x | |
n |= pSrc[1]; // xx12 | |
n <<= 8; // x12x | |
n |= pSrc[2]; // x123 | |
((WORD*)pDst)[0]= Base64Digits8192[ n >> 12 ]; //A little trick to write 2 bytes at a time | |
((WORD*)pDst)[1]= Base64Digits8192[ n & 0x00000fff ]; | |
nLenSrc -= 3; | |
pDst += 4; //jump 2*2bytes at a time | |
pSrc += 3; | |
} | |
if ( nLenSrc > 0 ) { // some left after last triple | |
int n1= (*pSrc & 0xfc) >> 2; | |
int n2= (*pSrc & 0x03) << 4; | |
if (nLenSrc > 1 ) { // corrected. Thanks to jprichey | |
pSrc++; | |
n2 |= (*pSrc & 0xf0) >> 4; | |
} | |
*pDst++ = Base64Digits[n1]; // encode at least 2 outputs | |
*pDst++ = Base64Digits[n2]; | |
if (nLenSrc == 2) { // 2 src bytes left to encode, output xxx= | |
int n3= (*pSrc & 0x0f) << 2; | |
pSrc++; | |
n3 |= (*pSrc & 0xc0) >> 6; | |
*pDst++ = Base64Digits[n3]; | |
} | |
if (nLenSrc == 1) { // 1 src byte left to encode, output xx== | |
*pDst++ = '='; | |
} | |
*pDst++ = '='; | |
} | |
//Create the resulting object and free the memory | |
//further memory allocation should be caught by nodejs context | |
Local<v8::String> result =v8::String::New(p); | |
free(p); | |
//free(pDst); | |
return scope.Close(result ); | |
} | |
void init(Handle<Object> target){ | |
target->Set(String::NewSymbol("toBase64Fast"), | |
FunctionTemplate::New(Method)->GetFunction()); | |
} | |
NODE_MODULE(base64, init) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"targets":[ | |
{ | |
"target_name":"base64", | |
"sources": [ "base64.cc" ] | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int ToBase64Fast( const BYTE* pSrc, int nLenSrc, char* pDst, int nLenDst ) | |
{ | |
int nLenOut= ((nLenSrc+2)/3)*4; // 4 out for every 3 in, rounded up | |
if ( nLenOut+1 > nLenDst ) { | |
return( 0 ); // fail! | |
} | |
WORD* pwDst= (WORD*)pDst; | |
while( nLenSrc > 2 ) { | |
DWORD n= pSrc[0]; // xxx1 | |
n <<= 8; // xx1x | |
n |= pSrc[1]; // xx12 | |
n <<= 8; // x12x | |
n |= pSrc[2]; // x123 | |
pwDst[0]= Base64Digits8192[ n >> 12 ]; | |
pwDst[1]= Base64Digits8192[ n & 0x00000fff ]; | |
nLenSrc -= 3; | |
pwDst += 2; | |
pSrc += 3; | |
} | |
// -------------- end of buffer special handling (see text) | |
pDst= (char*)pdwDst; | |
if ( nLenSrc > 0 ) { // some left after last triple | |
int n1= (*pSrc & 0xfc) >> 2; | |
int n2= (*pSrc & 0x03) << 4; | |
if (nLenSrc > 1 ) { // corrected. Thanks to jprichey | |
pSrc++; | |
n2 |= (*pSrc & 0xf0) >> 4; | |
} | |
*pDst++ = Base64Digits[n1]; // encode at least 2 outputs | |
*pDst++ = Base64Digits[n2]; | |
if (nLenSrc == 2) { // 2 src bytes left to encode, output xxx= | |
int n3= (*pSrc & 0x0f) << 2; | |
pSrc++; | |
n3 |= (*pSrc & 0xc0) >> 6; | |
*pDst++ = Base64Digits[n3]; | |
} | |
if (nLenSrc == 1) { // 1 src byte left to encode, output xx== | |
*pDst++ = '='; | |
} | |
*pDst++ = '='; | |
} | |
// *pDst= 0; nLenOut++ // could terminate with NULL, here | |
return( nLenOut ); | |
} | |
WORD Base64Digits8192[ 4096 ]; | |
void SetupTable8192() | |
{ | |
for ( int j=0; j<64; j++ ) { | |
for ( int k=0; k<64; k++ ) { | |
WORD w; | |
w = Base64Digits[k] << 8; | |
w |= Base64Digits[j]; | |
Base64Digits8192[(j*64)+k]= w; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is a little bug when encoding 3k+2 buffer length and the next char is not NULL.
The correct code should be as following:
int ToBase64Fast( const BYTE* pSrc, int nLenSrc, char* pDst, int nLenDst )
{
int nLenOut= ((nLenSrc+2)/3)4; // 4 out for every 3 in, rounded up
if ( nLenOut+1 > nLenDst ) {
return( 0 ); // fail!
}
WORD pwDst= (WORD*)pDst;
while( nLenSrc > 2 ) {
DWORD n= pSrc[0]; // xxx1
n <<= 8; // xx1x
n |= pSrc[1]; // xx12
n <<= 8; // x12x
n |= pSrc[2]; // x123
}
// -------------- end of buffer special handling (see text)
pDst= (char_)pdwDst;
if ( nLenSrc > 0 ) { // some left after last triple
int n1= (_pSrc & 0xfc) >> 2;
int n2= (_pSrc & 0x03) << 4;
if (nLenSrc > 1 ) { // corrected. Thanks to jprichey
pSrc++; // this is already the last character in case of 3k+2 buffer length
n2 |= (_pSrc & 0xf0) >> 4;
}
_pDst++ = Base64Digits[n1]; // encode at least 2 outputs
*pDst++ = Base64Digits[n2];
if (nLenSrc == 2) { // 2 src bytes left to encode, output xxx=
int n3= (_pSrc & 0x0f) << 2;
// pSrc++; // no increment necessary as it would be outside the buffer and if it is not NULL then a bad encoding result is produced
// n3 |= (*pSrc & 0xc0) >> 6; // not necessary as the next element is considered NULL
*pDst++ = Base64Digits[n3];
}
if (nLenSrc == 1) { // 1 src byte left to encode, output xx==
*pDst++ = '=';
}
*pDst++ = '=';
}
// *pDst= 0; nLenOut++ // could terminate with NULL, here
return( nLenOut );
}
WORD Base64Digits8192[ 4096 ];
void SetupTable8192()
{
for ( int j=0; j<64; j++ ) {
for ( int k=0; k<64; k++ ) {
WORD w;
w = Base64Digits[k] << 8;
w |= Base64Digits[j];
Base64Digits8192[(j*64)+k]= w;
}
}
}