I need to split a hex string at every 00 byte. I tried this:
string.split('00');
But that causes splits at 5009, for instance, which is incorrect because it is splitting a byte in half.
In other words, it turns 5009 to [5, 9], which I don't want. But I do want it to turn af0059 to [af, 59].
Is it even possible to split bytes using regex, without cutting any bytes in half?
I could use a loop to seek through the string and only divide the string at even-number indices, but I would much prefer a regex expression.
Because of the byte sizes, you need to first split the string into byte-sizes, then map and finally join.
const string = "af00b9e00f70";
const res = string.split(/([\d\w]{4})/).filter(e => e).map(e => e.replace(/00([\d\w]{2})/, "$1").replace(/([\d\w]{2})00/, "$1")).join("");
console.log(res);
Here's a somewhat "old school' approach, but it demonstrates the principal. I say "old school' because we had to do this all the time back in the days of assembler coding. 'string' contains your long string of hex pairs (bytes). Here I convert it to byte values. Change the 'string' to whatever you want, but be sure it has an even number of hex digits. Call 'translate' to demonstrate it, and format the output into an alert() (or just output to the console)
var values = []; // output array
var string = "000102030405060708090a0b0c0d0e0f1FFFFEFDFCFBFAF9F8F7F6F5F4F3F2F0";
function getHexByteValues( string) {
var hex= "0123456789ABCDEF";
var outIx=0;
for (var i =0; i <= (string.length-2); i +=2) { // skip every other
//get higher and lower nibble
var hexdig1 = string.substring(i, i+1);
var hexdig0 = string.substring(i+1, i+2);
// for simplicity, convert alpha to upper case
hexdig1 = hexdig1.toUpperCase();
hexdig0 = hexdig0.toUpperCase();
// convert hex to decimal value.
// position in lookup string == value
var dec1 = hex.indexOf(hexdig1);
var dec0 = hex.indexOf(hexdig0);
// calc "byte" value, and add to values.
values[outIx++] = dec1 * 16 + dec0;
}
}
function translate(string) {
getHexByteValues(string);
var output="";
for (var i =0; i < values.length; i++) {
output += i + " = " + values[i] + "\r\n";
}
alert (output);
}
Maybe not the most elegant, but it works
const inp = "af00b9e00f70"
const out = inp.match(/.{1,2}/g).map(a=>a=="00"?"_":a).join("").split("_");
console.log(out);
I'm trying to convert a hexadecimal string to string with Windows-1251 encoding. I need to use JavaScript. I've tried using this sample that someone posted:
var win1251 = new TextDecoder("windows-1251");
for (var i = 0x00; i < 0xFF; i++) {
var hex = (i <= 0x0F ? "0" : "") + i.toString(16).toUpperCase();
decodeMap[hex] = win1251.decode(Uint8Array.from([i]));
}
but I can't seem to make it work. Can someone please help out?
Propably you're using it in incorrect way.
The code in you post creates dictionary (hex => windows-1251).
So, to translate hex string to windows-1251 string you have to:
split your hex string into array with 2-hex elements
Translate every element to windows-1251
Join result array into string
var decodeMap = {};
var win1251 = new TextDecoder("windows-1251");
for (var i = 0x00; i < 0xFF; i++) {
var hex = (i <= 0x0F ? "0" : "") + i.toString(16).toUpperCase();
decodeMap[hex] = win1251.decode(Uint8Array.from([i]));
}
var number = "3230313830363131313535303435303831";
var hexarr = number.toUpperCase().match(/[0-9A-F]{2}/g)
var win1251arr = hexarr.map(el=> decodeMap[el]);
console.log(win1251arr.join(""))
You can also do it in much shorter way (directly translate your hex string without creating dictionary):
var win1251 = new TextDecoder("windows-1251");
var number = "3230313830363131313535303435303831";
var arr = number.toUpperCase().match(/[0-9A-F]{2}/g).map(el=>"0x"+el);
var uarr = Uint8Array.from(arr);
console.log(win1251.decode(uarr));
If your browser doesn't support TextDecoder, you can use dictionary from first snippet:
var decodeMap = getHexToWin1251Dictionary();
var number = "3230313830363131313535303435303831";
var hexarr = number.toUpperCase().match(/[0-9A-F]{2}/g)
var win1251arr = hexarr.map(el=> decodeMap[el]);
console.log(win1251arr.join(""))
// function below returns content of decodeMap from first snippet
function getHexToWin1251Dictionary(){
return {"10":"\u0010","11":"\u0011","12":"\u0012","13":"\u0013","14":"\u0014","15":"\u0015","16":"\u0016","17":"\u0017","18":"\u0018","19":"\u0019","20":" ","21":"!","22":"\"","23":"#","24":"$","25":"%","26":"&","27":"'","28":"(","29":")","30":"0","31":"1","32":"2","33":"3","34":"4","35":"5","36":"6","37":"7","38":"8","39":"9","40":"#","41":"A","42":"B","43":"C","44":"D","45":"E","46":"F","47":"G","48":"H","49":"I","50":"P","51":"Q","52":"R","53":"S","54":"T","55":"U","56":"V","57":"W","58":"X","59":"Y","60":"`","61":"a","62":"b","63":"c","64":"d","65":"e","66":"f","67":"g","68":"h","69":"i","70":"p","71":"q","72":"r","73":"s","74":"t","75":"u","76":"v","77":"w","78":"x","79":"y","80":"Ђ","81":"Ѓ","82":"‚","83":"ѓ","84":"„","85":"…","86":"†","87":"‡","88":"€","89":"‰","90":"ђ","91":"‘","92":"’","93":"“","94":"”","95":"•","96":"–","97":"—","98":"","99":"™","00":"\u0000","01":"\u0001","02":"\u0002","03":"\u0003","04":"\u0004","05":"\u0005","06":"\u0006","07":"\u0007","08":"\b","09":"\t","0A":"\n","0B":"\u000b","0C":"\f","0D":"\r","0E":"\u000e","0F":"\u000f","1A":"\u001a","1B":"\u001b","1C":"\u001c","1D":"\u001d","1E":"\u001e","1F":"\u001f","2A":"*","2B":"+","2C":",","2D":"-","2E":".","2F":"/","3A":":","3B":";","3C":"<","3D":"=","3E":">","3F":"?","4A":"J","4B":"K","4C":"L","4D":"M","4E":"N","4F":"O","5A":"Z","5B":"[","5C":"\\","5D":"]","5E":"^","5F":"_","6A":"j","6B":"k","6C":"l","6D":"m","6E":"n","6F":"o","7A":"z","7B":"{","7C":"|","7D":"}","7E":"~","7F":"","8A":"Љ","8B":"‹","8C":"Њ","8D":"Ќ","8E":"Ћ","8F":"Џ","9A":"љ","9B":"›","9C":"њ","9D":"ќ","9E":"ћ","9F":"џ","A0":" ","A1":"Ў","A2":"ў","A3":"Ј","A4":"¤","A5":"Ґ","A6":"¦","A7":"§","A8":"Ё","A9":"©","AA":"Є","AB":"«","AC":"¬","AD":"","AE":"®","AF":"Ї","B0":"°","B1":"±","B2":"І","B3":"і","B4":"ґ","B5":"µ","B6":"¶","B7":"·","B8":"ё","B9":"№","BA":"є","BB":"»","BC":"ј","BD":"Ѕ","BE":"ѕ","BF":"ї","C0":"А","C1":"Б","C2":"В","C3":"Г","C4":"Д","C5":"Е","C6":"Ж","C7":"З","C8":"И","C9":"Й","CA":"К","CB":"Л","CC":"М","CD":"Н","CE":"О","CF":"П","D0":"Р","D1":"С","D2":"Т","D3":"У","D4":"Ф","D5":"Х","D6":"Ц","D7":"Ч","D8":"Ш","D9":"Щ","DA":"Ъ","DB":"Ы","DC":"Ь","DD":"Э","DE":"Ю","DF":"Я","E0":"а","E1":"б","E2":"в","E3":"г","E4":"д","E5":"е","E6":"ж","E7":"з","E8":"и","E9":"й","EA":"к","EB":"л","EC":"м","ED":"н","EE":"о","EF":"п","F0":"р","F1":"с","F2":"т","F3":"у","F4":"ф","F5":"х","F6":"ц","F7":"ч","F8":"ш","F9":"щ","FA":"ъ","FB":"ы","FC":"ь","FD":"э","FE":"ю"};
}
Let's say I have a string variable called myString, and another string variable called myChar.
var myString = "batuhan"; // it's user input.
var myChar = "0"; // will be one character, always
What I need is, a function that returns all the combinations of myString and myChar.
Like:
"batuhan","batuha0n","batuh0an","batuh0a0n","batu0han","batu0ha0n","batu0h0an","batu0h0a0n","bat0uhan","bat0uha0n","bat0uh0an","bat0uh0a0n","bat0u0han","bat0u0ha0n","bat0u0h0an","bat0u0h0a0n","ba0tuhan","ba0tuha0n","ba0tuh0an","ba0tuh0a0n","ba0tu0han","ba0tu0ha0n","ba0tu0h0an","ba0tu0h0a0n","ba0t0uhan","ba0t0uha0n","ba0t0uh0an","ba0t0uh0a0n","ba0t0u0han","ba0t0u0ha0n","ba0t0u0h0an","ba0t0u0h0a0n","b0atuhan","b0atuha0n","b0atuh0an","b0atuh0a0n","b0atu0han","b0atu0ha0n","b0atu0h0an","b0atu0h0a0n","b0at0uhan","b0at0uha0n","b0at0uh0an","b0at0uh0a0n","b0at0u0han","b0at0u0ha0n","b0at0u0h0an","b0at0u0h0a0n","b0a0tuhan","b0a0tuha0n","b0a0tuh0an","b0a0tuh0a0n","b0a0tu0han","b0a0tu0ha0n","b0a0tu0h0an","b0a0tu0h0a0n","b0a0t0uhan","b0a0t0uha0n","b0a0t0uh0an","b0a0t0uh0a0n","b0a0t0u0han","b0a0t0u0ha0n","b0a0t0u0h0an","b0a0t0u0h0a0n"
Rules: myChar shouldn't follow myChar
How can I do that? Really my brain dead right now :/
It's possible to implement what you want using recursion.
// Example: allCombinations("abcd", "0") returns the array
// ["abcd", "abc0d", "ab0cd", "ab0c0d", "a0bcd", "a0bc0d", "a0b0cd", "a0b0c0d"]
function allCombinations(str, chr) {
if (str.length == 1)
return [str];
var arr = allCombinations(str.substring(1), chr);
var result = [];
var c = str.charAt(0);
for (var i = 0; i < arr.length; i++)
result.push(c + arr[i]);
for (var i = 0; i < arr.length; i++)
result.push(c + chr + arr[i]);
return result;
}
You may or may not have noticed this but this is basically counting in binary. If we define bit 0 to be the absence of myChar and bit 1 to be the presence of myChar, then the following sequence:
var myString = ".....";
var myChar = "1";
var sequence = [
".....1",
"....1.",
"....1.1",
"...1.."
];
is basically counting from 1 to 4 in binary:
var sequence = [
0b0000001,
0b0000010,
0b0000011,
0b0000100
];
Therefore, all you need is a for loop to count up to the bit amount of the length of the string plus 1 (because the position at the end of the string is also legal):
var len = Math.pow(2,myString.length+1);
for (var x = 0; x < len; x++) {
// x in binary is all the possible combinations
// now use the "1" bits in x to modify the string:
// Convert myString to array for easy processing:
var arr = myString.split('');
arr.push(""); // last position;
for (var i = myString.length; i >= 0; i--) {
if ((x >> i) & 0x01) { // check if bit at position i is 1
arr[i] = myChar + arr[i];
}
}
console.log(arr.join('')); // print out one combination
}
Of course, this works only for small strings of up to 31 characters. For larger strings you'd need to do the binary counting using things other than numbers. Doing it in a string form is one option. Another option is to use a bigint library such as BigInteger.js to do the counting.