Base64 - File is damaged - javascript

I'm trying to upload a pdf file through javascript. I have the base64 representation of the file and I decode it. The file is uploaded but that data seems to be corrupt.
The error message says "The file is damaged and could not be repaired" when I try opening the file.
I get the base64 string server side like so...
byte[] buffer = new byte[length];
var postedFile = httpRequest.Files[file];
postedFile.InputStream.Read(buffer, 0, length);
string encodedString = Convert.ToBase64String(buffer);
Here is the ajax call I make to upload the file
var data= Base64.decode(result); //result is the base64 encoded string
$.ajax({
url: url,
type: "POST",
data: data,
processData: false,
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": _digetsValue,
"content-length": length
},
success: function (data)
{
alert("it worked");
},
error: function (err)
{
}
});
For decoding, I'm using this chunk of code...
or from here How can you encode a string to Base64 in JavaScript?
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 +
Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
Base64._keyStr.charAt(enc3) + Base64._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 = Base64._keyStr.indexOf(input.charAt(i++));
enc2 = Base64._keyStr.indexOf(input.charAt(i++));
enc3 = Base64._keyStr.indexOf(input.charAt(i++));
enc4 = Base64._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;
}
}
Originally, I was doing something like this...
getFileBuffer = function (file)
{
var deferred = $.Deferred();
var reader = new FileReader();
reader.onload = function (e)
{
deferred.resolve(e.target.result);
}
reader.onerror = function (e)
{
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(file);
return deferred.promise();
};
But of course this is exclusive to HTML5 and whatnot. So when I would call my ajax function, I would pass in this arraybuffer from the file reader and voila! It would work. Now I'm trying to mimic the same sort of functionality with IE8. Is this possible?
Thanks

I wrote some functions a while ago I believe to be binary safe, here are the relevant ones for you; base64To6 and (perhaps poorly named) base6To8.
var chars = (
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz' +
'0123456789+/'
),
inver = {}, i;
for (i = 0; i < chars.length; ++i) {
inver[chars[i]] = i;
}
function base64To6(b64) {
var arr6 = [],
i = b64.length, lenMod = 0;
while (b64.charAt(--i) === '=')
++lenMod;
for (i = 0; i < b64.length - lenMod; ++i)
arr6.push(inver[b64.charAt(i)]);
i = b64.length & 3;
if (i) i = 4 - i;
i = i + b64.length;
arr6.byteLength = 3 * i / 4 - lenMod;
return arr6;
}
function base6To8(arr6) {
var arr8 = [], i,
e1, e2, e3,
s1, s2, s3, s4,
d1, d2, d3, d4;
for (i = 0; i < arr6.length; i += 4) {
s1 = (d1 = arr6[i] ) & 63;
s2 = (d2 = arr6[i + 1]) & 63;
s3 = (d3 = arr6[i + 2]) & 63;
s4 = (d4 = arr6[i + 3]) & 63;
// xxxxxx xxyyyy yyyyzz zzzzzz
e1 = ( s1 << 2) + (s2 >>> 4);
e2 = ((s2 & 15) << 4) + (s3 >>> 2);
e3 = ((s3 & 3) << 6) + s4 ;
arr8.push(e1);
if (d3 !== undefined)
arr8.push(e2, e3);
else if (d2 !== undefined )
arr8.push(e2);
}
if (arr6.byteLength !== undefined)
arr8.length = +arr6.byteLength;
return arr8;
}
Now if you do
var int8arr = base6to8(base64to6(data));
You will have an Array of Integers (at most 8 bit numbers), which the Base64 was representing. JavaScript does not use Int8 for Number so you can't immediately use this Array.
Unfortunately, as far as I know, IE8 does not support UInt8Array or Blob, which would let you then happily work with the binary data, so I'm not sure exactly where you'd want to take it from here.

Related

How to send regex expression from JavaScript to PHP

I try to send the regular expression \d+-\d+-\d+T\d+:\d+:\d+\+\d+:\d+\sINFO\s\(\d\):\sSTARTE\sKundenimport to my PHP webserver.
So I tried to Base64 encode the string before sending it. Base64.encode(startRegex)
function test(logfile, startRegex, endRegex)
{
return $.ajax({
url: "ajax.php",
type: "POST",
data: {
action: "getAllStrBetween",
inputStr: logfile,
startRegex: Base64.encode(startRegex),
endRegex: Base64.encode(endRegex)
}
});
}
/**
*
* 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 = 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;
}
}
I also used this code on PHP side to turn off magic quotes:
<?php
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
if (isset($_POST['startRegex'])) {
$startRegex = base64_decode(filter_input(INPUT_POST, "startRegex"));
}
echo $startRegex; //Output: "d+-d+-d+Td+:d+:d++d+:d+sINFOs(d):sSTARTEsKundenimport"
But I get this output: "d+-d+-d+Td+:d+:d++d+:d+sINFOs(d):sSTARTEsKundenimport"
Thanks in advance for any help.

Create file and invoke download using JavaScript

I want to dynamically create a JSON file in my JS code and also invoke the download of that file?
Any chance I can do that in JavaScript?
THANKS!!
Either use a server side language and GET vars (don't forget to set the MIME type to something like application/octet-stream) or base64 encode the JSON into a Data URI if you aren't worried about supporting legacy browsers.
Here's an example; try writing some text and then pressing download. Only problem is you can't control the filename:
<!DOCTYPE HTML>
<html>
<head>
<title>Data URI</title>
<script>
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;
}
}
window.onload=function(){
document.getElementById('download').onclick=function(){
window.open("data:application/octet-stream;base64,"+Base64.encode(document.getElementById('text').value));
}
}
</script>
</head>
<body style="margin:0;padding:0;overflow:hidden;">
<textarea id="text"></textarea>
<input type="button" value="Download" style="height:auto;width:100px" id="download"/>
</body>
</html>
Yes you can, but you need to create this file as a string.
Then, call:
window.location = window.URL.createObjectURL(new Blob([what_is_in_your_file], {type: "application/json"}));

Base64 decoding is not working for binary data

well I need a Base64 decoding function. But it is not returning desired output when i am working with binary data. I know atob and atob functions but my problem is I am implementing it in workers and the user agent chrome. chrome not at implemented atob, btoa functions in workers, so suggest me a base64 functions that works with binary data. Now I am using the below function it is not working for binary data.
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;
}
}
Thanks in advance!!
I did a quick search and found a decoder that claims to decode binary data, though I have not tried it:
https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js

How to base64 encode inside of javascript

I am trying to implement a simple script on a site that will return base64 encoded information from google's ajax API. This is what I am playing with so far:
<html>
<head>
<script src="http://www.google.com/jsapi?key=ABQIAAAA0duujonFsEX871htGWZBHRS76H0qhS7Lb-D1Gd0Mnaiuid8Z7BQIyz2kMpojKizoyiCQA4yRkKAKug" type="text/javascript"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function() {
var location = 'Unable to determine your location.';
if (google.loader.ClientLocation) {
var loc = google.loader.ClientLocation;
location = 'Country: <strong>' + loc.address.country + '</strong>, Region: <strong>' + loc.address.region + '</strong>, City: <strong>' +
loc.address.city + '</strong>, Lat/Long: <strong>' + loc.latitude + ', ' + loc.longitude + '</strong>';
}
jQuery('.geolocation').html(location);
});
</script>
</head>
<body>
<span class="geolocation"></span>
</body>
</html>
It returns the info I am trying to get properly, but I need to base64 encode the separate parts such as country, region, city, lat and longitude. In php it would be simple, but I cannot figure out how to do it in javascript. Any help would be appreciated.
Mozilla, WebKit and Opera all have btoa() and atob() functions for base 64 encoding and decoding respectively. Use those where possible because they will almost certainly be massively faster than a JavaScript implementation and fall back to one of the many scripts that turn up when you do a web search.
EDIT 10 SEPTEMBER 2013: atob() and btoa() do not handle Unicode characters outside the ASCII range. MDN has workarounds but I can't vouch for them. Thanks to #larspars for pointing this out.
For example, if you were using the example from amphetamachine's answer, you could do the following:
if (!window.btoa) {
window.btoa = function(str) {
return Base64.encode(str);
}
}
if (!window.atob) {
window.atob = function(str) {
return Base64.decode(str);
}
}
alert( btoa("Some text") );
This answer seems to match what you're looking for.
There's also this one which is more elegant:
/**
*
* 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 = 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;
}
}
IE 10 & above and all latest browser
Encode String
var str = "raj";
var enc = window.btoa(str); // cmFq
Decode String
var dec = window.atoa('cmFq'); // raj
Or else you might have your own function on page. small blog with references
I have part of the code from the answer here:
https://scotch.io/quick-tips/how-to-encode-and-decode-strings-with-base64-in-javascript
and the other part from the answer on this page:
https://stackoverflow.com/a/3776796/2655623
and here is the result:
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
window.btoa = function(str) {
return Base64.encode(str);
}
window.atob = function(str) {
return Base64.decode(str);
}
As this keep everything in one place, I won't involve myself with how window.atb / window.btoa act different in various browsers.

Silverlight to Javascript interop UTF encoding/decoding

How do I get both alerts, one invoked from silverlight and the other invoked from javascript, to show the same data in the same way.
eg. ���� != ýÿýÿý
System.Windows.Browser.HtmlPage.Window.Alert( data );
alert(parameters);
Silverlight3 code, sending data to javascript function:
System.Windows.Browser.HtmlPage.Window.Alert( data );
// data contains binary data read from files
data = Convert.ToBase64String(Encoding.UTF8.GetBytes(data));
HtmlPage.Window.Eval("var data='"+data+"'makePOSTRequest('"+this.url+"',data);");
javascript function:
function makePOSTRequest(url,parameters)
{
...
parameters = UTF8.encode(decode64(parameters));
alert(parameters);
...
}
javascript library:
var UTF8 = {
// public method for url encoding
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;
},
// public method for url decoding
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;
}
}
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 = 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);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}
function decode64(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
alert("There were invalid base64 characters in the input text.\n" +
"Valid base64 characters are A-Z, a-z, 0-9, �+�, �/�, and �=�\n" +
"Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
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);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}
Do you need to UTF-8 encode your characters, or do you just need a way to get these characters into the JavaScipt string? I would recommend using unicode escape sequences (see Unicode at at Mozilla Developer Center). For example, the copyright character is represented as "\u00A9". The nice thing about unicode escape sequences is they can exist in a source file that is encoded using iso-8859-1, but still allow for any unicode character.
See Converting Unicode strings to escaped ascii string for an example of how to do generate these escape sequences in C#.
You seem to be encoding the data as UTF-8 twice, you do it in silverlight:-
Encoding.UTF8.GetBytes(data)
and you do it again in Javascript
parameters = UTF8.encode(decode64(parameters));
are you sure this line shouldn't be:-
parameters = UTF8.decode(decode64(parameters));
?
Is there a reason you're not using WebClient or WebRequest inside Silverlight to do this posting?

Categories

Resources