Reputation: 933
I'm attempt to convert a base64 string generated from javascript code using C# code, but I'm running into an invalid length message.
The string is MQA5ADIAMwA3ADgANwA6ADAA0
It should convert back to 1923787:0
I tried a number of online decoders and some of them worked but a couple failed with the same invalid length error. I'll not post links here, but needless to say they were able to convert it back to the expected string.
C# Decode
var t = "MQA5ADIAMwA3ADgANwA6ADAA0";
var x = Convert.FromBase64String(t);
Javascript encoder:
var encoder = function (mL) {
if (!mL || mL === '') {
return '';
}
var ei = [];
var V;
for (V = 0; V < mL.length; V++) {
ei.push(mL.charCodeAt(V) % 256);
ei.push(Math.floor(mL.charCodeAt(V) / 256));
}
ei.push(0);
ei.push(0);
var sf = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
var gF = [],
hO;
for (V = 0; V < ei.length - 1; V += 3) {
hO = ei[V] * 0x10000 + ei[V + 1] * 0x100 + ei[V + 2];
gF.push(sf.charAt(Math.floor(hO / 0x40000)));
gF.push(sf.charAt(Math.floor(hO / 0x1000) % 0x40));
gF.push(sf.charAt(Math.floor(hO / 0x40) % 0x40));
gF.push(sf.charAt(hO % 0x40));
}
var vr = Math.ceil(mL.length * 16 / 6);
while (gF.length > vr) {
gF.pop();
}
if ((gF.length % 4) === 3) {
gF.push('1');
} else if ((gF.length % 4) === 2) {
gF.push('2');
} else if ((gF.length % 4) === 0) {
gF.push('0');
}
return gF.join('');
};
Upvotes: 0
Views: 1521
Reputation: 66364
First, change your for
which does the encode to
for (V = 0; V < ei.length - 3; V += 3) {
then instead of
var vr = Math.ceil(mL.length * 16 / 6);
while (gF.length > vr) {
gF.pop();
}
if ((gF.length % 4) === 3) {
gF.push('1');
} else if ((gF.length % 4) === 2) {
gF.push('2');
} else if ((gF.length % 4) === 0) {
gF.push('0');
}
do
switch (ei.length % 3) {
case 0:
break;
case 1:
gF[gF.length - 2] = '=';
case 2:
gF[gF.length - 1] = '=';
break;
}
Now you'll get
encoder("1923787:0"); // "MQA5ADIAMwA3ADgANwA6ADA="
Which is valid Base64,
What's going on? Base64 uses =
to designate the number of bytes we started with, in terms of how short we were from the next multiple of 3
, so this swaps out the final characters (which were the zero symbol due to not having any bits) with those =
signs.
The modification to the loop is to end the loop at the right place - you were overshooting with just - 1
because say you were at V >= ei.length - 3
but V < ei.length - 1
, i.e. V = ei.length - 3
or V = ei.length - 2
you would enter the next iteration at V = ei.length
or V = ei.length + 1
, at which point ei[V], ei[V+1], ei[V+2]
would be undefined
Upvotes: 2
Reputation: 15237
The correct Base64 encoding of your input string is "MQA5ADIAMwA3ADgANwA6ADAA" - without the trailing zero that you show. For some reason your javascript code is adding that zero. I'm not sure why. But that makes it an invalid string.
I'm guessing the padding, which should be '=' is being added as '0' by the javascript algorithm. Just a thought though.
Upvotes: 0
Reputation: 119116
Your encoding routine is putting an extra 0 on the end of the string, remove it and the decode will work (into a Unicode string)
Example code:
var original = "1923787:0";
var bytesFromOriginal = System.Text.Encoding.Unicode.GetBytes(original);
var base64string = Convert.ToBase64String(bytesFromOriginal);
base64string = "MQA5ADIAMwA3ADgANwA6ADAA";
var bytesFromEncodedString = Convert.FromBase64String(base64string);
var decodedString = System.Text.Encoding.Unicode.GetString(bytesFromEncodedString);
Upvotes: 0
Reputation: 1009
See if this helps.
string x = Encoding.UTF8.GetString(Convert.FromBase64String("MQA5ADIAMwA3ADgANwA6ADAA0"));
Link: How do I decode a base64 encoded string?
Upvotes: 0