Byte array Data splitting - javascript

I am reading data froma device. The Data is a serial number. I am getting it from a Byte array, and its gives me the data in HEX format. The Serial number data it gives me is as follows:
010203040506070809. How do I split the numbers and only display every second number combined together so I get 123456789?
I am using ESP32 reading from a PCB with RS485 posting to a webserver using .js.
No Idea what to do in this instance.

Means to extract every second number in the serial number and combine them together, you can convert the hexadecimal string into a byte array, and then iterate through every other byte and convert it back to a hexadecimal string. Finally, you can concatenate the hexadecimal strings to get the desired output.
const hexString = "010203040506070809";
let serialNumber = "";
for (let i = 1; i < hexString.length; i += 2) {
serialNumber += hexString[i];
}
console.log(serialNumber); // Output: 123456789

const s = '010203040506070809';
const n = +[...s].filter((_,i)=>i%2).join('')
console.log(n)
console.log(typeof n)

Related

How would one convert a UUID type to ULID type?

Theres a bit documentation out there how to convert ULID to UUID but not so much when you need to convert UUID to ULID.
I'm looking at this UUID / ULID generator / converter https://www.ulidtools.com/
but I'm not quite sure how I would replicate the UUID to ULID conversion, the source is too obfuscated for me to understand.
I'm not sure where to even begin, is this conversion even safe ? will it guarantee a unique conversion ?
Pure Javascript Method for conversion:
Converting a UUID to a ULID guarantee a unique code. ULIDs are unique 128-bit identifiers that are generated based on a combination of the current timestamp.
function convertUUIDtoULID(uuid) {
const uuidBinary = uuid.split("-").map((hex) => parseInt(hex, 16));
return uuidBinary
.slice(0, 8)
.map((byte) => byte.toString(32))
.concat(uuidBinary.slice(8).map((byte) => byte.toString(32)))
.join("");
}
const uuid = "454391df-b950-42ea-a2c0-92d62c215d67";
const ulid = convertUUIDtoULID(uuid);
console.log(ulid);
The function takes in a string of UUID format as an input
It splits the UUID string at each "-" character and converts each
resulting hexadecimal string into a decimal number using the
parseInt() function with base 16.
It creates a new array of the first 8 decimal numbers from the UUID
and converts each number to a base-32 string using the toString()
function with base 32.
It concatenates this array with a new array of the remaining decimal
numbers from the UUID, also converted to base-32 strings.
The resulting array of base-32 strings is joined together into a
single string, which is returned as the ULID.
The example UUID string is passed into the function and the resulting
ULID string is logged to the console.
You can also use [https://www.npmjs.com/package/ulid] for converting UUID to ULID
I've had the same issue and I took a look at ulidtools.com then after digging into its source code for a while I found that it uses this package behind the seen.
import pkg from "id128";
const { Ulid, Uuid4 } = pkg;
const ulid = Ulid.generate();
const ulidToUuid = Uuid4.fromRaw(ulid.toRaw());
const uuidToUlid = Ulid.fromRaw(ulidToUuid.toRaw());
console.table([
{
generated_ulid: ulid.toCanonical(),
converted_to_uuid: ulidToUuid.toCanonical(),
converted_back_to_ulid: uuidToUlid.toCanonical(),
},
]);

How can I split( a binary-containing string at a specific binary value?

Overview:
I'm building a Javascript tool inside a web page. Except for loading that page, the tool will run without server communication. A user will select a local file containing multiple binary records, each with a x'F0 start byte and x'F0 end byte. The data in between is constrained to x'00 - x'7F and consists of:
bit maps
1-byte numbers
2-byte numbers, low order byte first
a smattering of ASCII characters
The records vary in lengths and use different formats.
[It's a set of MIDI Sysex messages, probably not relevant].
The local file is read via reader.readAsArrayBuffer and then processed thus:
var contents = event.target.result;
var bytes = new Uint8Array(contents);
var rawAccum = '';
for (x = 0; x < bytes.length; x++) {
rawAccum += bytes[x];
}
var records = rawAccum.split(/\xF0/g);
I expect this to split the string into an array of its constituent records, deleting the x'F0 start byte in the process.
It actually does very little. records.length is 1 and records[0] contains the entire input stream.
[The actual split code is: var records = rawAccum.split(/\xF0\x00\x00\x26\x02/g); which should remove several identical bytes from the start of each record. When this failed I tried the abbreviated version above, with identical (non)results.]
I've looked at the doc on split( and at several explanations of \xXX among regex references. Clearly something does not work as I have deduced. My experience with JavaScript is minimal and sporadic.
How can I split a string of binary data at the occurrence of a specific binary byte?
The splitting appears to work correctly:
var rawAccum = "\xf0a\xf0b\xf0c\xf0"
console.log( rawAccum.length); // 7
var records = rawAccum.split(/\xF0/g);
console.log(records); // "", "a", "b", "c", ""
but the conversion of the array buffer to a string looks suspicious. Try converting the unsigned byte value to a string before appending it to rawAccum:
for (x = 0; x < bytes.length; x++) {
rawAccum += String.fromCharCode( bytes[x]);
}
Data conversions (update after comment)
The filereader reads the file into an array buffer in memory, but JavaScript does not provide access to array buffers directly. You can either create and initialize a typed array from the buffer (e.g. using the Uint8Array constructor as in the post), or access bytes in the buffer using a DataView object. Methods of DataView objects can convert sequences of bytes at specified positions to integers of varying types, such as the 16 bit integers in the Midi sysex records.
JavaScript strings use sequences of 16 bit values to hold characters, where each character uses one or two 16 bit values encoded using UTF-16 character encoding. 8 bit characters use only the lower 8 bits of a single 16 bit value to store their Unicode code point.
It is possible to convert an array buffer of octet values into a "binary string", by storing each byte value from the buffer in the low order bits of a 16 bit character and appending it to an existing string. This is what the post attempts to do. But in JavaScript strings (and individual characters which have a string length of 1) are not a subset of integer numbers and have their own data type, "string".
So to convert an unsigned 8 bit number to a JavaScript 16 bit character of type "string", use the fromCharCode static method of the global String object, as in
rawAccum += String.fromCharCode( bytes[x]);
Calling String.fromCharCode is also how to convert an ASCII character code located within MIDI data to a character in JavaScript.
To convert a binary string character derived from an 8 bit value back into a number, use the String instance method charCodeAt on a string value and provide the character position:
var byteValue = "\xf0".charCodeAt(0);
returns the number 0xf0 or 250 decimal.
If you append a number to a string, as in the question, the number is implicitly converted to a decimal string representation of its value first:
"" + 0xf0 + 66 // becomes the string "24066"
Note that an array buffer can be inspected using a Uint8Array created from it, sliced into pieces using the buffer's slice method and have integers of various types extracted from the buffer using data views. Please review if creating a binary string remains the best way to extract and interpret Midi record contents.

Javascript - parsing a hex value

I am trying to parse a hex value to decode a card
The hex data I receive from the card is f8b2d501f8ff12e0056281ed55
First I am converting this to an integer with parseInt()
var parseData = parseInt('f8b2d501f8ff12e0056281ed55', 16);
The value recieved is 1.9703930145800871e+31
When I try to decode this using the bitwise operator in Javascript
var cardNumber = ((parseData & 0xFFFFF) >> 1).toString();
I received a 0 value.
What am I doing wrong here, how can I parse the value of such large integer number?
There are two ways to do it:
First, notice that & 0xFFFFF operation in your code is just equivalent to getting a substring of a string (the last 5 characters).
So, you can just do a substring from the end of your number, and then do the rest:
var data = 'b543e1987aac6762f22ccaadd';
var substring = data.substr(-5);
var parseData = parseInt(substring, 16);
var cardNumber = ((parseData & 0xFFFFF) >> 1).toString();
document.write(cardNumber);
The second way is to use any big integer library, which I recommend to you if you do any operations on the large integers.
Since the number integer is so big you should use any bigNum library for js.
I recommend BigInteger, since you are working only with integers and it supports bitwise operations, however you can also check this answer for more options.

Sum up two values from a data layer with Javascript

I'd like to sum up to two (string) values.
The values come from a data layer. I know how to get the data out of the data layer,
return datalayer.path123.infoABC;
but I don't know how to sum them with JS.
All input is appreciated!
The value with the quotes is the String "1" where as the value without the quotes is the number 1. If you add those together the answer will be the String "11".
If you want to get the sum as a number you first need to convert the String into a number. You can do this by passing it to the Number() function. Since I don't know which is the string in your case I'll just conver both to a number to be safe.
var a = Number(datalayer.path123.infoABC);
var b = Number(datalayer.path123.infoDEF);
var sum = a + b;

Fast conversion of an array of unsigned integers to base64

I have a VBArray in Javascript containing a long set of 8-bit unsigned integers, more than 1'000'000 entries usually.
I can easily transform it to a conventional array or Uint8Array, and my goal is to obtain its base64 representation.
I have tried the methods here, but running
var b64encoded = btoa(String.fromCharCode.apply(null, _uint8Array));
throws an out of stack space exception.
The conversion in itself is not a problem, because I could write my own conversion method which does the following
create empty bit string
foreach value in the array
get binary with toString(2)
pad the binary to make it 8-bit
add it to the bit string
Base64 conversion is then trivial.
Performance, as you can imagine, is rather poor. Any suggestions on how to improve this?
You could try something like this to limit the number of arguments, thus reducing the required stack space:
var A = new Uint8Array(10000000), s = '';
// Encode at most 49152 bytes at a time
for (var i = 0; i < A.length; i += 49152) {
s += btoa(String.fromCharCode.apply(null, A.subarray(i, i + 49152)));
}
You can change the number 49152 to anything that is both under the browser's limit and divisible by 3.

Categories