Converting from a Uint8Array to a string and back
I’m having an issue converting from a particular Uint8Array to a string and back. I’m working in the browser and in Chrome which natively supports the TextEncoder/TextDecoder modules. If I start with a simple case, everything seems to work well: const uintArray = new TextEncoder().encode(‘silly face demons’); // Uint8Array(17) [115, 105, 108, 108, 121, 32, 102, 97, 99, 101, 32, 100, 101, 109, 111, 110, 115] new TextDecoder().decode(uintArray); // silly face demons But the following case is not giving me the results I expect. Without getting into too much of the details (it’s cryptography related), let’s start with the fact that I’m provided with the following Uint8Array: Uint8Array(24) [58, 226, 7, 102, 202, 238, 58, 234, 217, 17, 189, 208, 46, 34, 254, 4, 76, 249, 169, 101, 112, 102, 140, 208] and what I want to do is to convert that to a string and then later decrypt the string back to the original array, but I get this: const uintArray = new Uint8Array([58, 226, 7, 102, 202, 238, 58, 234, 217, 17, 189, 208, 46, 34, 254, 4, 76, 249, 169, 101, 112, 102, 140, 208]); new TextDecoder().decode(uint8Array); // :�f��:����.»�L��epf�� new TextEncoder().encode(‘:�f��:����.»�L��epf��’); . which results in: Uint8Array(48) [58, 239, 191, 189, 7, 102, 239, 191, 189, 239, 191, 189, 58, 239, 191, 189, 239, 191, 189, 17, 239, 191, 189, 239, 191, 189, 46, 34, 239, 191, 189, 4, 76, 239, 191, 189, 239, 191, 189, 101, 112, 102, 239, 191, 189, 239, 191, 189] The array has doubled. Encoding is a bit out of my wheel house. Can anyone tell me why the array has doubled (I’m assuming it’s an alternate representation of the original array. ). Also, and more importantly, is there a way I could get back to the original array (i.e. undouble the one I’m getting)?
It is simple: Not all byte values correspond to string characters. Not in ASCII or unicode. Also there is misuse of encrypt/decrypt encode/decode, they are not the same thing.
If you want only to convert it into string and back and get coresponding values, you can do: var str = String.fromCharCode(. uintArray) and then Uint8Array.from([. str].map(ch => ch.charCodeAt()))
How to convert an Uint8Array to string in Javascript
Learn multiple ways to convert an Uint8Array to string in Javascript.
Working with node.js or other javascript platforms (multioperability), you’ll find that some methods decide to return something different than a string. An Uint8Array is a typed array that represents an array of 8-bit unsigned integers.
The following list of methods , provide a collection of efficient ways to convert an Uint8Array to a regular string in javascript.
Little strings
The following method is acceptable for little arrays (>=100k characters), otherwise you’ll get exceptions as RangeError : Maximum call stack size exceeded or Out of stack space . However you need to know that this method doesn’t play good with UTF-8 characters.
function uint8arrayToStringMethod(myUint8Arr)
Browser implementation
If your javascript is being executed in a browser, you can make use of the TextEncoder and TextDecoder native functions which allow you to choose which codification you want to use. The Encoding API helps solving the string conversion problem.
/** * Convert an Uint8Array into a string. * * @returns */ function Decodeuint8arr(uint8array) < return new TextDecoder("utf-8").decode(uint8array); >/** * Convert a string into a Uint8Array. * * @returns */ function Encodeuint8arr(myString)
Crossplatform method
The following method is very useful and works pretty good. It doesn’t use any hacks nor depends on Browser JS functions, e.g. works also in other JS environments. Works through the UTF-8 convention.
// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt /* utf.js - UTF-8 UTF-16 convertion * * Copyright (C) 1999 Masanao Izumo [email protected]> * Version: 1.0 * LastModified: Dec 25 1999 * This library is free. You can redistribute it and/or modify it. */ function Utf8ArrayToStr(array) < var out, i, len, c; var char2, char3; out = ""; len = array.length; i = 0; while(i < len) < c = array[i++]; switch(c >> 4) < case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx out += String.fromCharCode(c); break; case 12: case 13: // 110x xxxx 10xx xxxx char2 = array[i++]; out += String.fromCharCode(((c & 0x1F) > return out; >
Large blocks
If your data block is huge, you may want to use a method that works properly with huge data (an async method). In this case we’ll create blob that contains our Uint8Array and then we’ll use the file reader to read it as text.
/** * Converts an array buffer to a string * * @param uint8arr | The buffer to convert * @param callback | The function to call when conversion is complete */ function largeuint8ArrToString(uint8arr, callback) < var bb = new Blob([uint8arr]); var f = new FileReader(); f.onload = function(e) < callback(e.target.result); >; f.readAsText(bb); > // Usage example // "Hello" in Uint8Array format var myuint8Arr = new Uint8Array([72, 101, 108, 108, 111, 32, 33]); largeuint8ArrToString(myuint8Arr,function(text)< // Hello console.log(text); >);
Note: as said before, this method is recommendable only if you handle huge datasets.
How to convert the object of Uint8Array to string?
I have same problem as this question. I see the answer but I couldn’t understand how I can do it. Is there any other suggestions? My code is:
var eccrypto = require("eccrypto"); var w,actual; var publicKey = Buffer.from([4, 86, 82, 58, 244, 11, 140, 41, 132, 245, 184, 162, 163, 98, 49, 119, 168, 235, 252, 50, 6, 91, 147, 191, 190, 61, 65, 63, 101, 164, 132, 213, 188, 106, 26, 203, 171, 215, 240, 151, 7, 193, 10, 151, 103, 107, 1, 135, 117, 225, 5, 41, 55, 57, 18, 205, 98, 178, 82, 135, 170, 111, 188, 98, 57],'hex'); var privateKey= Buffer.from([238, 239, 199, 101, 188, 134, 13, 13, 195, 172, 125, 168, 225, 189, 72, 148, 225, 200, 127, 218, 204, 11, 150, 146, 180, 243, 195, 109, 200, 119, 50, 20],'hex'); eccrypto.encrypt(publicKey, Buffer.from("message")).then(function(encrypted) < console.log(encrypted) let encoded =JSON.stringify(encrypted) w=encoded; console.log(encoded) actual = JSON.parse((encoded)) console.log(actual) >); eccrypto.decrypt(privateKey,actual).then(function(plaintext) < console.log("Message to part B:", plaintext.toString()); >);
Uncaught (in promise) Error: Bad public key
this the output of encrypted : this the output of encoded :
and this the output of actual «there is some things changes i think, is not it ?»:
thank you advance.
Convert UInt8Array to String
I’m working on an application involving cryptocurrency, and I’m having trouble with handling the conversion of some of the data involved. I’m using bitcoinjs-lib to generate Bitcoin addresses. The addresses are created successfully, and my response object looks like the following:
address: "1Nnn9HpxgykWXxZX5rL3hIH7iikWkQaBSc" balance: 0 currency: "BTC" privateKey: Uint8Array(32) [86, 201, 0, 216, 118, 231, 201, 251, 161, 22, 223, 14, 234, 229, 168, 146, 41, 121, 182, 136, 176, 120, 185, 173, 181, 47, 228, 244, 107, 230, 29, 27] publicKey: Uint8Array(33) [3, 233, 119, 81, 11, 119, 13, 133, 115, 183, 163, 90, 218, 2, 36, 41, 105, 158, 248, 131, 68, 234, 193, 110, 105, 72, 38, 110, 253, 192, 245, 108, 214] wif: "Kz8QjBvSPjfRVxazJDwGEGwaoGTjRhFGe1MPsiPZRPpKEpidH7Qf"
I’m using an IndexedDB to store the created wallets. Since I’m generating different types of wallets, my database call looks like this:
My data is stored in my database just fine, except I can’t correctly translate the UInt8Array into a string. I’ve tried nearly everything from this post, but have not had any success. Here is the bytesToString function that I tried:
function bytesToString (bytes)
I tried using Node’s StringDecoder module with no success. I’ve also tried using Buffer.from(privateKey).toString(‘utf-8’) . I’ve read that Bitcoin addresses use a base 58 encoding. I don’t know if that’s relevant or not. I don’t have any experience using buffers, or with any type of conversion like this. Any help would be greatly appreciated.