Base64 encode on number in javascript - javascript

I used this base64 and uriencode on a number
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/core-min.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script>
var num= '1418265869452';
var base64num = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(salt));
var encodeuri = encodeURIComponent(base64num);
</script>
base64 num gives me MTQxODI2NTg2OTQ1Mg==
But actually i also needs to uri encode it after base64 encode
when i tried to encodeURIComponent(base64num) it throwed me an error as follows:
Exception thrown from JavaScript : Error: Malformed UTF-8 data
How to achieve this

I've never seen encodeURIComponent throw JS errors. Its probably someplace in the third party library. Depending on your browser support requirements you might be able to use the built in base64 encoder/decoders
var base64num = btoa('1418265869452'),
encodeuri = encodeURIComponent(base64num);
encodeuri; // "MTQxODI2NTg2OTQ1Mg%3D%3D"
This could also be happening when you try to decode it. First you have to decodeURIComponent before trying to base64 decode it.

You are passing salt variable as a parameter, but I am not seeing any initialization of it. Instead you need to pass num, then it will start working, as I have used num in place of salt and is working perfectly fine at my end.
Here is the updated JSFiddle Link
Updated Code:
var num= '1418265869452';
var base64num = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(num));
var encodeuri = encodeURIComponent(base64num);
alert(encodeuri);

Related

React : "DOMException: String contains an invalid character" error while encoding in base64

I'm facing a new kind of error and I'm kind of stuck here. I have a lightweight code editor in my app and I send its content (typed by the user) to my back-end, encoding it in base64.
First I used codeContent.toString("base64"); method and it worked like a charm with this kind of testing content :
let numberTest = 52;
let arrayTest = [63, 24, 75];
let sumTest = numberTest + arrayTest[0];
The problem here, is that I can't decode it back to UTF-8 when I want to retrieve this code from my API, I get some gibberish.
So I tried this method instead : atob(codeContent);. In this case, if I type a simple text like : test, the encoded version looks fine (µë-), but the content is still empty in my backend after my POST. And if I try this with a simple line of JS like let testNumber = 52;, then I get this error : "DOMException: String contains an invalid character"
To sum it up : I'm a little lost, what's the good way to encode my text to base64 and retrieve it afterwards ?
My problem was that I understood atob and btoa wrong : I thought btoa decoded FROM base64, but it's the other way around.
So, encoding TO base64 :
btoa(unescape(encodeURIComponent(str)));
And decoding base64 :
decodeURIComponent(escape(window.atob(str)));

decode url before location change in react app

Hey guys can you help me solve next issue? For example we have url like site.com/post?comments=1,2,3,4 after I paste it in browser address string, my app opens and url decodes to site.com/post?comments=1%2C2%2C3%2C4, how to get rid of %2C in url and save it in original way and vice versa if someone opens url like site.com/post?comments=1%2C2%2C3%2C4 decode it to site.com/post?comments=1,2,3,4? I know that I can use method lice decodeURIComponent, but I don't know where and in which moment exactly apply it. I'm using react and react-router. Any ideas?
You can use decodeURIComponent for decoding and encodeURIComponent and encoding. To see the result run the snippet below:
console.log(decodeURIComponent(`site.com/post?comments=1%2C2%2C3%2C4`));
console.log(encodeURIComponent(`site.com/post?comments=1,2,3,4`));
The %2 that you see is due to the "," in your URL, for encoding and decoding you can use the library https://www.npmjs.com/package/base-64
var base64 = require('base-64');
var bytes = site.com/post?comments=1,2,3,4
var encoded = base64.encode(bytes);
console.log(encoded);

DOM Exception 5 INVALID CHARACTER error on valid base64 image string in javascript

I'm trying to decode a base64 string for an image back into binary so it can be downloaded and displayed locally by an OS.
The string I have successfully renders when put as the src of an HTML IMG element with the data URI preface (data: img/png;base64, ) but when using the atob function or a goog closure function it fails.
However decoding succeeds when put in here: http://www.base64decode.org/
Any ideas?
EDIT:
I successfully got it to decode with another library other than the built-in JS function. But, it still won't open locally - on a Mac says it's damaged or in an unknown format and can't get opened.
The code is just something like:
imgEl.src = 'data:img/png;base64,' + contentStr; //this displays successfully
decodedStr = window.atob(contentStr); //this throws the invalid char exception but i just
//used a different script to get it decode successfully but still won't display locally
the base64 string itself is too long to display here (limit is 30,000 characters)
I was just banging my head against the wall on this one for awhile.
There are a couple of possible causes to the problem. 1) Utf-8 problems. There's a good write up + a solution for that here.
In my case, I also had to make sure all the whitespace was out of the string before passing it to atob. e.g.
function decodeFromBase64(input) {
input = input.replace(/\s/g, '');
return atob(input);
}
What was really frustrating was that the base64 parsed correctly using the base64 library in python, but not in JS.
I had to remove the data:audio/wav;base64, in front of the b64, as this was given as part of the b64.
var data = b64Data.substring(b64Data.indexOf(',')+1);
var processed = atob(data);

Problem passing data from Javascript to Flex

I am using ExternalInterface in Flex to retrieve AMF encoded string from Javascript. The problem is the AMF encoded string sometimes contains \u0000 which causes the ExternalInterface to return null instead of the encoded string from Javascript.
Any idea how to solve this?
Thanks in advance.
The \0000 is falsely interpreted as EOF when reading external data. The same thing happens when it appears in XML files, as well.
You should be able to replace it with an unambiguous character sequence before passing the string to Flash, and back upon reception in ActionScript. In the JavaScript function, use something like
return returnString.replace (/\0000/g, "{nil}");
This should remove the unwanted \0000 characters from the string before returning it to Flash.
On the Flash side, use
receiveString = receiveString.replace (/\{nil\}/g, "\u0000");
directly after receiving the data.
Encoding the pyamf AMF output to base64 will do the trick.
Here is the encoding part in python:
encoder = pyamf.get_encoder(pyamf.AMF3)
encoder.writeObject(myObject)
encoded = base64.b64encode(encoder.stream.getvalue())
Here is the decoding part in AS3:
var myDecoder:Base64Decoder = new Base64Decoder();
myDecoder.decode(base64EncodedString);
var byteArr:ByteArray = myDecoder.toByteArray()
byteArr.position = 0;
var input:Amf3Input = new Amf3Input();
input.load(byteArr);
var test:MyObject = input.readObject();

Returning a byte string to ExternalInterface.call throws an error

I am working on my open source project Downloadify, and up until now it simply handles returning Strings in response to ExternalInterface.call commands.
I am trying to put together a test case using JSZip and Downloadify together, the end result being that a Zip file is created dynamically in the browser, then saved to the disk using FileReference.save. However, this is my problem:
The JSZip library can return either a base64 encoded string of the Zip, or the raw byte string. The problem is, if I return that byte string in response to the ExternalInterface.call command, I get this error:
Error #1085: The element type "string" must be terminated by the matching end-tag "</string>"
ActionScript 3:
var theData:* = ExternalInterface.call('Downloadify.getTextForSave',queue_name);
Where queue_name is just a string used to identify the correct instance in JS.
JavaScript:
var zip = new JSZip();
zip.add("test.txt", "Hello world!\n");
var content = zip.generate(true);
return content;
If I instead return a normal string instead of the byte string, the call works correctly.I would like to avoid using base64 as I would have to include a base64 decoder in my swf which will increase its size.
Finally: I am not looking for a AS3 Zip generator. It is imperative to my project to have that part run in JavaScript
I am admittedly not a AS3 programmer by trade, so if you need any more detail please let me know.
When data is being returned from javascript calls it's being serialized into an XML string. So if the "raw string" returned by JSZip will include characters which make the XML non-valid, which is what I think is happening here, you'll get errors like that.
What you get as a return is actually:
<string>[your JSZip generated string]</string>
Imagine your return string includes a "<" char - this will make the xml invalid, and it's hard to tell what character codes will a raw byte stream translate too.
You can read more about the external API's XML format on LiveDocs
i think the problem is caused by the fact, that flash expects a utf8 String and you throw some binary stuff at it. i think for example 0x00FF will not turn out to be valid utf8 ...
you can try fiddling around with flash.system::System.setCodePage, but i wouldn't be too optimistic ...
i guess a base64 decoder is probably really the easiest ... i'd rather worry about speed than about file size though ... this rudimentary decoder method uses less than half a K:
public function decodeBase64(source:String):ByteArray {
var ret:ByteArray = new ByteArray();
var map:Object = new Object();
var i:int = 0;
for each (var char:String in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("")) map[char] = i++;
map["="] = 0;
source = source.split("\n").join("").split("\r").join("");//remove linebreaks
for (i = 0; i < source.length/4; i++) {
var buf:int = 0;
for each (char in source.substr(i * 4, 4).split("")) buf = (buf << 6) + map[char];
ret.writeByte(buf >>> 16);
ret.writeShort(buf);
}
return ret;
}
you could simply shorten function names and take a smaller image ... or use ColorTransform or ConvolutionFilter on one image instead of four ... or compile the image into the SWF for smaller overall size ... or reduce function name length ...
so unless you're planning on working with MBs of data, this is the way to go ...

Categories