As a personal project, I'm writing a 6502 emulator in JavaScript (HTML5 based). I'm porting some bits of it from a predecessor I created in C. To load in the files (ROMs in my case), I could use this C code:
unsigned char* buffer = calloc(1, 4096);
FILE* file = fopen("xyz", "rb");
fread(buffer, 1, 4096, file);
fclose(file);
and access it like this:
char firstChar = buffer[0];
short nextShort = (buffer[2] << 8) | buffer[1];
free(buffer);
Now, I need to be able to port this to JavaScript. For input, I can do something like this using a file input:
var file = document.getElementById("picker").files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
From here, I have reader.result as a giant, base64 encoding of the file. I need a way to access the binary file as I did in the beginning C example, where I can simply get the values (or use simple bitwise operations)
I'm guessing the most feasible solution would be an array of values 0-255, but I just need access, regardless of how.
#bfavaretto pointed me in the correct direction
var file = document.getElementById("picker").files[0];
var reader = new FileReader();
reader.readAsArrayBuffer(file);
var buffer = new Uint8Array(reader.result);
Which can then be accessed as buffer[0] for the first byte.
I'm the author of simplebuf library. It allows quick binary parsing/serialization and is purely written in javascript.
Example:
var layout = [
sb.field("len", sb.type.uint(32)),
sb.field("padding", sb.type.uint(32)),
sb.field("id", sb.type.string_dynamic("len"))
];
var original = {len: 4, "padding": 999, "id": "1234"};
sb.write(buffer, 0, original, layout);
https://github.com/conceptacid/simplebuf.js
Related
I'm getting a binary file from my computer in javascript. And this binary file contains some long numbers in the following:
20
56599565 6559565
65656589 6595956
26989565 5656595
...
My question is that how can I get these numbers?
I have a binary file that contains numbers, its created with serialization on c++. And the first 40 bytes of this binary file is empty. After these 40 bytes have passed, my numbers are starting to come.
My solution:
After reading the file successfully I have an ArrayBuffer right? And I know that my numbers start from the 40. bytes. So I sliced it.
// rawData ArrayBuffer(197283) {}
var frameCount = rawData.slice(40,48);
var frameCountView = new Float64Array(frameCount);
And then what should I do?
I think we can get the Int8Array from Arraybuffer;
// rawData ArrayBuffer(197283) {}
var fileContent = rawData.slice(40);
var frameCountView = new Int64Array(fileContent);
var byteArray = new BigUint64Array(fileContent);
How to save (with the lowest file size) pixels data in javascript?
For now I'm using JSON and it is looking like this:
{"SIZE":[120,120],
"FRAME":["SHINE",""],
"LEDS":[
{"X":0,"Y":0,"R":16,"G":30,"B":58},
{"X":1,"Y":0,"R":13,"G":23,"B":43},
{"X":2,"Y":0,"R":14,"G":26,"B":50},
etc...
So for little pictures like 16x16, 90x32 the file size is ok but now I need do pictures 120x120 and file size is around 500kb. Is there any better solution for that?
You have few options to send your pixels data in minimal size. The easiest way is to pack all this pixel information in one binary data.
MIME type
You can send image data with http request using i.e. image/bmp MIME type. You can view https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data to check how to read that kind of data
var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; // Note: not oReq.responseText
if (arrayBuffer) {
var byteArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteArray.byteLength; i++) {
// do something with each byte in the array
}
}
};
oReq.send(null);
Convert to binary and send it as BASE64
You can convert your pixels data to binary format (similar to pure BMP) and then use BASE64 algorithm to represent it with letters. Then you can send it with regular JSON
This is very good explanation about packing complex structures to binary: http://danthedev.com/2015/07/25/binary-in-javascript/
I want to create an HOTP client using javascript similar to SpeakEasy
The above library is intended for server side javascript usage and it uses NodeJS.
I want to do the same thing on front end javascript in a browser but I haven't been able to use CryptoJS to achieve this behavior.
var key = "abc";
var counter = "123";
// create an octet array from the counter
var octet_array = new Array(8);
var counter_temp = counter;
for (var i = 0; i < 8; i++) {
var i_from_right = 7 - i;
// mask 255 over number to get last 8
octet_array[i_from_right] = counter_temp & 255;
// shift 8 and get ready to loop over the next batch of 8
counter_temp = counter_temp >> 8;
}
// There is no such class called as Buffer on Browsers (its node js)
var counter_buffer = new Buffer(octet_array);
var hash = CryptoJS.HmacSHA1(key,counter_buffer);
document.write("hex value "+ hash);
document.write("hash value "+ CryptoJS.enc.Hex.stringify(hash));
I know this is possible on a native platform like java (android) or objective c (ios)
Here is the corresponding implementation HOTP in Objective C but I doubt if it's possible to do on a web based front end.
Also, I highly doubt if such a thing is secure in browser because javascript is viewable from any browser. Any inputs suggestions would be useful. I am doing this for a POC. I am curious if anyone has used Hotp on web based platform.
There is no such language that supports binary data strings in the code. You need to encode the binary data into some format such as Hex or Base64 and let CryptoJS decode it into it's own internal binary format which you then can pass to the various CryptoJS functions:
var wordArrayFromUtf = CryptoJS.enc.Utf8.parse("test");
var wordArrayFromHex = CryptoJS.enc.Hex.parse("74657374"); // "test"
var wordArrayFromB64 = CryptoJS.enc.Base64.parse("dGVzdA=="); // "test"
Other functions are:
wordArrayFromHex.toString(CryptoJS.enc.Utf8) // "test"
CryptoJS.enc.Utf8.stringify(wordArrayFromB64) // "test"
If you pass a string into a CrypoJS function (not these here), it will be assumed to be a Utf8-encoded string. If you don't want that, you need to decode it yourself.
The code at http://caligatio.github.io/jsSHA/ works fine for SHA-512.
Drop the .js files, look in their test/test.html at line 515. It might look like a string to you but it is binary hex.
So their input is binary which is unmistaken. Don't get hung up on the fact it is sitting in a big string.
I want to generate a file containing strings alongside Float32Arrays in my web app. I can write this data into a blob and then a file like this:
var myFirstFloat32Array = new Float32Array([42, 1, 2, 3]);
var myString = 'This is my string. It is a beautiful string.';
var blob = new Blob([
new Uint8Array([myFloat32Array.length]), // Store the size.
myFloat32Array,
new Uint8Array([myString.length]), // Store the size.
myString);
var downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(blob);
downloadLink.download = 'generatedFile';
downloadLink.innerHTML = 'Click to download generated file.';
So ... that successfully writes the file, but how do I read the string following the float 32 array?
I can read the first float32 array easily by reading the number from the first 4 bytes (which gives me the size of the array) and then constructing a Float32Array of that length.
However, how do I read the string? The string could contain characters outside of the ASCII range, so I can't just btoa the string, convert to a Uint8Array, and then write it.
Maybe I could convert the string to a blob first, get its size from the blob, and then somehow decode it later while reading (but how do I know the character encoding used later)?
What's the standard way to store string data alongside byte data in javascript for later decoding?
I am trying to emulate the following .NET code in javascript using the Crypto.js library.
var hashInput = "public=ID1000000001::routetype=POST::route=personsearch::key1=ID1000000001::key2=1043"
byte[] inputBytes = new byte[hashInput.Length * sizeof(char)];
System.Buffer.BlockCopy(hashInput.ToCharArray(), 0, inputBytes,0,inputBytes.Length);
byte[] keyBytes = HexadecimalStringToByteArray("A_HEX_STRING_GOES_HERE");
var hmac = HMACSHA256.Create();
hmac.Key = keyBytes;
var clientHash = hmac.ComputeHash(inputBytes);
This gives me a ByteArray which is used as part of POST to a WebAPI in the form of
[41,197,254,91,244,87.....] etc.
I want to make the same exact byte array in a javascript client but i am having diffculty getting this. I have tried the following:
var stringToHash = 'public=ID1000000001::routetype=POST::route=personsearch::key1=ID1000000001::key2=1043';
var privateKey = 'A_HEX_STRING_GOES_HERE';
var hash = CryptoJS.HmacSHA256(stringToHash, privateKey);
//this results in a WordArray, which can be converted to many types
//however i cannot get the byte array as in the .net example
//i.e. i just want to get [41,197,254,91,244,87....] etc.
I can see on the documentation for Crypto.js how to convert to base64, and other formats, but not to the ByteArray which i need.
Any ideas?
--UPDATE
Thanks for the advice on not using BlockCopy, and also for pointing me in the direction of the encoding issues which i had completely neglected.
This was part of the issue. The other part was that i had managed to misuse the HMACSHA256 class. I found (after several, several hours) that the .NET code was not producing the correct hash value.
It turns out this code DID produce the correct Hash:
var hashInput = "a::string::to::hash";
var privateKey = "C0B615950F9D577A4EAF64C9B4F2E50F3DA2C6BB6F790FA346E9732788B29A08AC5444F1B82984DB190A75D3861CC4802D598EBF0025FD1C327928F43EB1C80E";
byte[] inputBytes = Encoding.UTF8.GetBytes(hashInput);
byte[] keyBytes = Encoding.UTF8.GetBytes(privateKey);
HMACSHA256 hmac = new HMACSHA256(keyBytes);
hmac.Initialize();
var clientHash = hmac.ComputeHash(inputBytes);
var base64 = Convert.ToBase64String(clientHash);
Lucky for me my WebAPI is not live yet!
The problem is probably the character encoding. You should use for instance the method encode_utf8(stringValue) in JavaScript and new UTF8Encoding.getBytes(String value) in .NET, to make sure that the character encodings match. Note that modern cryptography is based on bytes, not on strings or characters. Using System.Buffer.BlockCopy() to encode characters is really bad practice.