简体   繁体   中英

Convert string to array of integers and vice versa in JavaScript

I have an array, each cell of which can keep 4 bytes (2**32). This array presents memory of my VM I write in JS. Also I have string. Only one place I can keep this string - memory which I describe above.

I decided to present strings in memory as C-strings (with special symbol NUL as the end of string). My current implementation looks ugly and I asking you advice, is there any way to improve this approach? Maybe there are any other way to do it?

Part of code, which converts string to array:

// demoMemory presents memory model
var DEMO_VOLUME = 16;
var demoMemory = new Array(DEMO_VOLUME);
for (var i = 0; i < DEMO_VOLUME; i++) demoMemory[i] = 0;

// convert string to hexidecimal string
var string = "Hello, World!", hexString = "";
for (var i = 0; i < string.length; i++) {
    hexString += string.charCodeAt(i).toString(16);
}

// convert hexidecimal string to array of strings
// each element of this array presents 4 symbols
var hexStringArray = hexString.match(/.{1,8}/g);

// add NUL (0x00) symbols to complete strings
while (hexStringArray[hexStringArray.length - 1].length != 8) {
    hexStringArray[hexStringArray.length - 1] += "00";
}

// convert to integer array
for (var i = 0; i < hexStringArray.length; i++) {
    demoMemory[i] = parseInt(hexStringArray[i], 16);
}

...and back to string:

// decode back to string
var resultString = "", decSymbolCode = 0;
for (var i = 0; i < demoMemory.length; i++) {
    hexString = demoMemory[i].toString(16);
    var hexSymbolCodeArray = hexString.match(/.{1,2}/g);
    for (var j = 0; j < hexSymbolCodeArray.length; j++) {
        decSymbolCode = parseInt(hexSymbolCodeArray[j], 16);
        resultString += String.fromCharCode(decSymbolCode);
    }
}

This code is inappreciable because I'm using JS Strings to build hexadecimal strings. I think it is possible to do with bitwise operations and masks, but I don't know, how. Maybe I'm wrong.

Here is a code that converts string to array of 32bit numbers and vice versa using masks and bitwise operations:

var demoMemory = [];

function stringToArray(str) {
  var i,
      length = str.length,
      arr = [];

  for(i=0; i<length; i+=4) {
    arr.push(
      (((str.charCodeAt(i)   || 0) << 24)
      |((str.charCodeAt(i+1) || 0) << 16)
      |((str.charCodeAt(i+2) || 0) << 8)
      |((str.charCodeAt(i+3) || 0)))
    );
  }

  if(length % 4 === 0) {
    arr.push(0);
  }

  return arr;
}

function arrayToString(arr) {
  var i, j, chrCode,
      length = arr.length,
      str = [];

  label:
  for(i=0; i<length; i++) {
    for(j=24; j>=0; j-=8) {
      chrCode = (arr[i] >> j) & 0xFF;
      if(chrCode) {
        str.push(String.fromCharCode(chrCode));
      } else {
        break label;
      }
    }
  }

  return str.join('');
}

console.log(demoMemory = stringToArray('Hello, World!')); // => [1214606444, 1865162839, 1869769828, 553648128]
console.log(arrayToString(demoMemory)); // "Hello, World!"

Working example you can find here: http://jsbin.com/aselug/2/edit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM