I am wondering how I can make the following bit shifting process in reverse?
chr1 = (enc1 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
This is basically shifting the bits for a decoding script Im using. Im wondering is there a way to reverse this process, for encoding instead of decoding?
This comes from the following script which decodes in base64:
Base64 = {
_keyStr: ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=",
decode: function( input ) {
var output = "";
var hex = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
var base64test = /[^A-Za-z0-9\+\.\=]/g;
do {
enc1 = this._keyStr.indexOf(input.charAt(i++)) ;
enc2 = this._keyStr.indexOf(input.charAt(i++)) ;
enc3 = this._keyStr.indexOf(input.charAt(i++)) ;
enc4 = this._keyStr.indexOf(input.charAt(i++)) ;
chr1 = (enc1 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return (output);
}
}
Observe the following calculations:
// enc = [0, 1, 0, 0]
chr1 = (0 | ((1 & 3) << 6)) = 64
chr2 = (1 >> 2) | ((0 & 0x0F) << 4) = 0
chr3 = (0 >> 4) | (0 << 2) = 0
// enc = [64, 0, 0, 0]
chr1 = (64 | ((0 & 3) << 6)) = 64
chr2 = (0 >> 2) | ((0 & 0x0F) << 4) = 0
chr3 = (0 >> 4) | (0 << 2) = 0
Since two inputs map to the same outputs, the function is not injective, i.e. cannot be reversed.
If you assume that all values of enc are <64, you can reverse it though:
enc1 = chr1 & 0x3f;
enc2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
enc4 = chr3 >> 2;
Since the space of values isn't that large, you can simply test them all out, right here in your browser:
'use strict';
function _indicate(status) {
var indicator = document.querySelector('.indicator');
while (indicator.firstChild) {
indicator.removeNode(firstChild);
}
indicator.setAttribute('class', status);
indicator.appendChild(document.createTextNode(status));
}
function test(enc1, enc2, enc3, enc4) {
var chr1 = (enc1 | ((enc2 & 3) << 6));
var chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
var chr3 = (enc3 >> 4) | (enc4 << 2);
var dec1 = chr1 & 0x3f;
var dec2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
var dec3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
var dec4 = chr3 >> 2;
if ((enc1 !== dec1) || (enc2 !== dec2) || (enc3 !== dec3) || (enc4 !== dec4)) {
console.log('FAIL');
console.log('chr ' + chr1 + ', ' + chr2 + ', ' + chr3);
console.log('Expected/got: ' + enc1 + '/' + dec1 + ', ' + enc2 + '/' + dec2 + ', ' + enc3 + '/' + dec3 + ', ' + enc4 + '/' + dec4);
_indicate('fail');
throw new Error('Failed test');
}
}
for (var enc1 = 0; enc1 < 63; enc1++) {
for (var enc2 = 0; enc2 < 63; enc2++) {
for (var enc3 = 0; enc3 < 63; enc3++) {
for (var enc4 = 0; enc4 < 63; enc4++) {
test(enc1, enc2, enc3, enc4);
}
}
}
}
_indicate('pass');
.fail {
background: red;
}
.pass {
background: green;
}
<div class="indicator"></div>
Related
I get the image from the user in form of formdata
This is how I made the Schema of the image
The Image is successfully in Monogodb
This is how I fetch information of images by Axios
I write code from rendering the image
This is how my wesite look when image is not been render
[I
Proper image on wesite
Proper image on wesite
where you are rendring the image using btoa method, this method is not present or deprecated in your framework, that's why you need to add that
first add -
var Base64 = new function() {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
this.encode = function(input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
}
return output;
}
this.decode = function(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
}
this._utf8_encode = function(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
this._utf8_decode = function(utftext) {
var string = "";
var i = 0;
var c = 0,
c1 = 0,
c2 = 0,
c3 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}()
And then to create a function
var btoa = Base64.encode;
now you can use your Code or
var image = 'data:image/jpeg;base64,' + btoa('your-binary-data');
<img src={image}/>
I am trying to create the .NET equivalent of Javascript code below. I've tried what I've shared in the ".NET SHA1" section but it generated different hash outputs. I tried translating javascript code into C# (which I've shared as well) which doesn't work either. What am I doing wrong, how can I get the same hash value generated by javascript function in C# ?
.NET SHA1 Hash:
public string CreateHash(string a, string b, string c)
{
string concatenation = string.Concat(a, b, c);
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] byt = Encoding.GetEncoding(0).GetBytes(concatenation);
byte[] hash = sha.ComputeHash(byt);
return Convert.ToBase64String(hash);
}
Javascript Code:
function createHash()
{
var hashdata = somestringconcat;
m.digest.value = encode64(sha1Hash(hashdata));
return 0;
}
var keyStr = "ABCDEFGHIJKLMNOP" +
"QRSTUVWXYZabcdef" +
"ghijklmnopqrstuv" +
"wxyz0123456789+/" +
"=";
function encode64(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = eval('0x' + input.charAt(i++) + input.charAt(i++));
if (i<input.length)
chr2 = eval('0x' + input.charAt(i++) + input.charAt(i++));
else
i=i+2;
if (i<input.length)
chr3 = eval('0x' + input.charAt(i++) + input.charAt(i++));
else
i=i+2;
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (i == input.length + 4) {
enc3 = enc4 = 64;
} else if (i == input.length + 2) {
enc4 = 64;
}
output = output +
keyStr.charAt(enc1) +
keyStr.charAt(enc2) +
keyStr.charAt(enc3) +
keyStr.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}
function sha1Hash(msg)
{
// constants [4.2.1]
var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
// PREPROCESSING
msg += String.fromCharCode(0x80); // add trailing '1' bit to string [5.1.1]
// convert string msg into 512-bit/16-integer blocks arrays of ints [5.2.1]
var l = Math.ceil(msg.length/4) + 2; // long enough to contain msg plus 2-word length
var N = Math.ceil(l/16); // in N 16-int blocks
var M = new Array(N);
for (var i=0; i<N; i++) {
M[i] = new Array(16);
for (var j=0; j<16; j++) { // encode 4 chars per integer, big-endian encoding
M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) |
(msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
}
}
// add length (in bits) into final pair of 32-bit integers (big-endian) [5.1.1]
// note: most significant word would be ((len-1)*8 >>> 32, but since JS converts
// bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14])
M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;
// set initial hash value [5.3.1]
var H0 = 0x67452301;
var H1 = 0xefcdab89;
var H2 = 0x98badcfe;
var H3 = 0x10325476;
var H4 = 0xc3d2e1f0;
// HASH COMPUTATION [6.1.2]
var W = new Array(80); var a, b, c, d, e;
for (var i=0; i<N; i++) {
// 1 - prepare message schedule 'W'
for (var t=0; t<16; t++) W[t] = M[i][t];
for (var t=16; t<80; t++) W[t] = ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
// 2 - initialise five working variables a, b, c, d, e with previous hash value
a = H0; b = H1; c = H2; d = H3; e = H4;
// 3 - main loop
for (var t=0; t<80; t++) {
var s = Math.floor(t/20); // seq for blocks of 'f' functions and 'K' constants
var T = (ROTL(a,5) + f(s,b,c,d) + e + K[s] + W[t]) & 0xffffffff;
e = d;
d = c;
c = ROTL(b, 30);
b = a;
a = T;
}
// 4 - compute the new intermediate hash value
H0 = (H0+a) & 0xffffffff; // note 'addition modulo 2^32'
H1 = (H1+b) & 0xffffffff;
H2 = (H2+c) & 0xffffffff;
H3 = (H3+d) & 0xffffffff;
H4 = (H4+e) & 0xffffffff;
}
return H0.toHexStr() + H1.toHexStr() + H2.toHexStr() + H3.toHexStr() + H4.toHexStr();
}
//
// function 'f' [4.1.1]
//
function f(s, x, y, z)
{
switch (s) {
case 0: return (x & y) ^ (~x & z);
case 1: return x ^ y ^ z;
case 2: return (x & y) ^ (x & z) ^ (y & z);
case 3: return x ^ y ^ z;
}
}
//
// rotate left (circular left shift) value x by n positions [3.2.5]
//
function ROTL(x, n)
{
return (x<<n) | (x>>>(32-n));
}
//
// extend Number class with a tailored hex-string method
// (note toString(16) is implementation-dependant, and
// in IE returns signed numbers when used on full words)
//
Number.prototype.toHexStr = function()
{
var s="", v;
for (var i=7; i>=0; i--) { v = (this>>>(i*4)) & 0xf; s += v.toString(16); }
return s;
}
C# Translation Attempt:
string Sha1Hash(string msg)
{
// constants [4.2.1]
uint[] K = new uint[] { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
// PREPROCESSING
msg += Convert.ToChar(0x80); // add trailing '1' bit to string [5.1.1]
// convert string msg into 512-bit/16-integer blocks arrays of ints [5.2.1]
uint l = (uint)Math.Ceiling(msg.Length / 4d) + 2; // long enough to contain msg plus 2-word length
uint N = (uint)Math.Ceiling(l / 16d); // in N 16-int blocks
uint[][] M = new uint[N][];
for (int i = 0; i < N; i++)
{
M[i] = new uint[16];
for (int j = 0; j < 16; j++)
{ // encode 4 chars per integer, big-endian encoding
M[i][j] = (uint)((Convert.ToChar(i * 64 + j * 4) << 24) | (Convert.ToChar(i * 64 + j * 4 + 1) << 16) |
(Convert.ToChar(i * 64 + j * 4 + 2) << 8) | (Convert.ToChar(i * 64 + j * 4 + 3)));
}
}
// add length (in bits) into final pair of 32-bit integers (big-endian) [5.1.1]
// note: most significant word would be ((len-1)*8 >>> 32, but since JS converts
// bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
M[N - 1][14] = (uint)Math.Floor(((msg.Length - 1) * 8) / Math.Pow(2, 32));
M[N - 1][15] = (uint)((msg.Length - 1) * 8) & 0xffffffff;
// set initial hash value [5.3.1]
ulong H0 = 0x67452301;
ulong H1 = 0xefcdab89;
ulong H2 = 0x98badcfe;
ulong H3 = 0x10325476;
ulong H4 = 0xc3d2e1f0;
// HASH COMPUTATION [6.1.2]
ulong[] W = new ulong[80];
ulong a, b, c, d, e;
for (int i = 0; i < N; i++)
{
// 1 - prepare message schedule 'W'
for (int t = 0; t < 16; t++) W[t] = M[i][t];
for (int t = 16; t < 80; t++) W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
// 2 - initialise five working variables a, b, c, d, e with previous hash value
a = H0; b = H1; c = H2; d = H3; e = H4;
// 3 - main loop
for (int t = 0; t < 80; t++)
{
ulong s = (ulong)Math.Floor(t / 20d); // seq for blocks of 'f' functions and 'K' constants
var T = (ROTL(a, 5) + F(s, b, c, d) + e + K[s] + W[t]) & 0xffffffff;
e = d;
d = c;
c = ROTL(b, 30);
b = a;
a = T;
}
// 4 - compute the new intermediate hash value
H0 = (H0 + a) & 0xffffffff; // note 'addition modulo 2^32'
H1 = (H1 + b) & 0xffffffff;
H2 = (H2 + c) & 0xffffffff;
H3 = (H3 + d) & 0xffffffff;
H4 = (H4 + e) & 0xffffffff;
}
return string.Concat(ToHexStr(H0), ToHexStr(H1), ToHexStr(H2), ToHexStr(H3), ToHexStr(H4));
}
ulong ROTL(ulong x, int n)
{
return ((x << n) | (x >> (32 - n)));
}
string ToHexStr(ulong param)
{
return ""; //
}
ulong F(ulong s, ulong x, ulong y, ulong z)
{
switch (s)
{
case 0: return (x & y) ^ (~x & z);
case 1: return x ^ y ^ z;
case 2: return (x & y) ^ (x & z) ^ (y & z);
case 3: return x ^ y ^ z;
}
return 0;
}
const string keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
string Encode64(string input)
{
string output = "";
int chr1 = 0;
int chr2 = 0;
int chr3 = 0;
int enc1, enc2, enc3, enc4 = 0;
var i = 0;
do
{
chr1 = Convert.ToInt32(("0x" + input[i++] + input[i++]), 16);
if (i < input.Length)
chr2 = Convert.ToInt32(("0x" + input[i++] + input[i++]), 16);
else
i = i + 2;
if (i < input.Length)
chr3 = Convert.ToInt32(("0x" + input[i++] + input[i++]), 16);
else
i = i + 2;
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (i == input.Length + 4)
{
enc3 = enc4 = 64;
}
else if (i == input.Length + 2)
{
enc4 = 64;
}
output = output +
keyStr[enc1] +
keyStr[enc2] +
keyStr[enc3] +
keyStr[enc4];
chr1 = chr2 = chr3 = 0;
enc1 = enc2 = enc3 = enc4 = 0;
} while (i < input.Length);
return output;
}
I have the following decode/encode routine. However, the encoding is not working properly (it should be printing "CMlaKA" not "ClaKA" to the console log). I think the problem is with the bit shifting, but I cant tell where.
Here is a jsfiddle to explain
https://jsfiddle.net/4yfrLv9y/16/
Here is the code (routine is run at the bottom)
var consoleLine = "<p class=\"console-line\"></p>";
console = {
log: function (text) {
$("#console-log").append($(consoleLine).html(text));
}
};
var Base64 = {
_keyStr: ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=",
encode : function (input) {
var output = [],
chr1, chr2, chr3, enc1, enc2, enc3, enc4,
i = 0;
while (i < input.length) {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 & 0x3f;
enc2 = (chr1 >> 6) | ((chr2 & 0x3c) << 2);
enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
enc4 = chr3 >> 2;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output.push([this._keyStr.charAt(enc1),
this._keyStr.charAt(enc2),
this._keyStr.charAt(enc3),
this._keyStr.charAt(enc4)].join(''));
}
return output.join('');
},
decodeAsArray: function (b) {
var d = this.decode(b),
a = [],
c;
//alert("decoded base64:" + d);
for (c = 0; c < d.length; c++) {
a[c] = d.charCodeAt(c)
}
//alert("returning a");
return a
},
decode: function( input ) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
enc1 = this._keyStr.indexOf(input.charAt(i++)) ;
enc2 = this._keyStr.indexOf(input.charAt(i++)) ;
enc3 = this._keyStr.indexOf(input.charAt(i++)) ;
enc4 = this._keyStr.indexOf(input.charAt(i++)) ;
chr1 = (enc1 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return (output);
}
};
basedecode();
function basedecode(){
//Converts 'CMlaKa to CcnK by base64'
var decoded = "CMlaKA"
//67 99 110 75 0 0 - This is the Byte Array, or ArrayBuffer of CcnK
decoded = Base64.decode(decoded)
console.log(decoded);
}
baseencode();
function baseencode(){
var encoded = [67,99,110,75];// byte array of CcnK
console.log(Base64.encode(encoded) + ' ---- Should be CMlaKA not ClaKA== - why is it different?');
}
I couldn't found your implementation algorithm, but found this one in wikipedia
and corrected yours
var consoleLine = "<p class=\"console-line\"></p>";
console = {
log: function (text) {
$("#console-log").append($(consoleLine).html(text));
}
};
var Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
encode : function (input) {
var output = [],
chr1, chr2, chr3, enc1, enc2, enc3, enc4,
i = 0;
while (i < input.length) {
chr1 = input.charCodeAt(i);
chr2 = input.charCodeAt(i+1);
chr3 = input.charCodeAt(i+2);
i+=3;
/* enc1 = chr1 && 0x3f;
enc2 = (chr1 >> 6) | ((chr2 & 0x3c) << 4);
enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 2);
enc4 = chr3 >> 2; */
var _24c = (chr1 << 16) + (chr2 << 8) + chr3;
//n = [(n >>> 18) & 63, (n >>> 12) & 63, (n >>> 6) & 63, n & 63];
enc1 = _24c >>> 18 & 63
enc2 = _24c >>> 12 & 63
enc3 = _24c >>> 6 & 63
enc4 = _24c & 63
/** if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
*/
output.push([this._keyStr.charAt(enc1),
this._keyStr.charAt(enc2),
this._keyStr.charAt(enc3),
this._keyStr.charAt(enc4)].join(''));
}
return output.join('');
},
decodeAsArray: function (b) {
var d = this.decode(b),
a = [],
c;
//alert("decoded base64:" + d);
for (c = 0; c < d.length; c++) {
a[c] = d.charCodeAt(c)
}
//alert("returning a");
return a
},
decode: function( input ) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
enc1 = this._keyStr.indexOf(input.charAt(i++)) ;
enc2 = this._keyStr.indexOf(input.charAt(i++)) ;
enc3 = this._keyStr.indexOf(input.charAt(i++)) ;
enc4 = this._keyStr.indexOf(input.charAt(i++)) ;
chr1 = (enc1 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return (output);
}
};
// basedecode();
function basedecode(){
//Converts 'CMlaKa to CcnK by base64'
var decoded = "CMlaKA"
//67 99 110 75 0 0 - This is the Byte Array, or ArrayBuffer of CcnK
decoded = Base64.decode(decoded)
console.log(decoded);
}
// baseencode();
function baseencode(){
var encoded = [67,99,110,75];// byte array of CcnK
console.log(Base64.encode(encoded) + ' ---- Should be CMlaKA not +la+A== - where do the + and = signs come from?');
}
function hashAndAssert(string_to_hash, result) {
var hash = Base64.encode(string_to_hash);
return '' + (hash == result) + ', expected: ' + result + '; output: ' + hash;
}
function unitTest() {
console.log('#1 Passed ' + hashAndAssert('', ''))
console.log('#2 Passed ' + hashAndAssert('foo', 'Zm9v'))
console.log('#1 Passed ' + hashAndAssert('foobar', 'Zm9vYmFy'))
}
unitTest();
There are a couple of mistakes in your code and they involve not only the encode method, but the decode one as well.
First of all, you are using a bad key string. Accoring to Wikipedia Wikipedia - Base64 'A' equals '0', not '.' as in your example.
This will prevent you from checking your code against public websites for validity.
This is the "standard" key string:
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
The '=' in the end is for padding and should not be used directly during conversion
Then, you got a problem with your byte shifting code.
You calculate the base64 values in the wrong direction. You should look at the Wikipedia link to see which bytes should be considered as each base64 value.
Here is a fixed snippet for the decoder:
chr1 = enc1 << 2 | ((enc2 & 0xc0) >> 6);
chr2 = ((enc2 & 0x0f) << 4) | ((enc3 & 0x3c) >> 2);
chr3 = ((enc3 & 0x03) << 6) | enc4;
Here is a fixed snippet for the encoder:
enc1 = (chr1 & 0xfc) >> 2;
enc2 = ((chr1 & 0x03) << 4) | ((chr2 & 0xf0) >> 4);
enc3 = ((chr2 & 0x0f) << 2) | ((chr3 & 0xc0) >> 6);
enc4 = chr3 & 0x3f;
Moreover, you must trim the output values (in the encoder) because they are in unlimited containers, so:
enc1 = enc1 & 0x3f;
enc2 = enc2 & 0x3f;
enc3 = enc3 & 0x3f;
Assuming you made all these changes, if the input to the decoder is "CMlaKA", the output is [12,217,155,44,16] and then the encoder will return the correct answer.
I'm trying to create a suitelet to allow users to upload a CSV file. Once loaded, it should get file contents and do something with it. Problem with the code below is that it's showing some kind of encoded text instead of the CSV content. It outputs fine when I upload a Txt file. I've tried to set the encoding as well but doesn't work.
var file = request.getFile("custpage_file");
//file.setEncoding("UTF-8");
var html = file.getValue();
response.write(html);
This works. It was from an older post I made to the NS User group. I think NS has a decoder that works although it's not documented. i.e. you can also try nlapiDecode(file.getValue(), 'base64');
function getFileValue(file){
if(file.getType() == "EXCEL") return normalize(Base64.decode(file.getValue()));
return normalize(file.getValue());
}
function normalize(val){ return val.replace("\r\n","\n");}
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = 0, c1 = 0, c2 = 0;
var c3 =0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
};
SuiteScript 2.0
var decode = encode.convert({
string: stringBase64,
inputEncoding: encode.Encoding.BASE_64,
outputEncoding: encode.Encoding.UTF_8
})
I have a search box that a user can search for any string including single AND double quotes, once they have searched, the backend is passing the keyword back to me so I can put it back in the box. I don't know what the string is so I can't escape quotes myself, below is an example:
var keyword = "hello";
$("#selectionkeywords").val();
The issue I am having is that if the user enters "hello" the keyword becomes ""hello"" and I get this error:
missing ) after argument list
[Break On This Error]
jQuery("#selectionkeywords").val(""hello"");
The user could also enter single quotes so that rules it out as well. I tried using escape unescape but I still have the same issue e.g. escape(""hello"")
I could get the value in an unescaped format e.g. "hello" but I don't know what to do with it, escape doesn't work on it I end up with this %26%23034%3Bhello%26%23034%3B
So I'm pretty much stuck at the moment as I can't do anything to the string, any ideas?
You have to escape the string server side, so javascript receives it already escaped, in the case of PHP you could do:
$var = str_replace('"', '\"', $var);
and then in javascript make sure you read it between double quotes, as you escaped for that:
//use double quotes, as you escaped for them
jQuery("#selectionkeywords").val("<?php echo $var ?>");
When you exchange data from server to client and viceversa, you want to use base64 encoding and decoding, in order to avoid this and other kinds of problems.
Java side:
import javax.xml.bind.DatatypeConverter;
/* ... */
/* Decode input from client */
String input = DatatypeConverter.printBase64Binary(inputFromClient);
/* Encode output for client */
String output = DatatypeConverter.printBase64Binary(encodedOutput);
Javascript side:
// Encode data for the server
var dataForServer = Base64.encode(data);
// Decode data coming from the server
var data = Base64.decode(dataFromServer);
using this class
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}