library cbor introduces a new value in the conversion - node.js

I made on node.js, this program, which has an anomaly. When I do decodeAllSync I get a vector of decimal numbers
which has one fewer numbers than I get by reconverting the vector with encodeAsync. Why don't I get the same vector?
Thank you
const cbor = require('cbor');
...
const results = cbor.decodeAllSync(output);
const input = cbor.encodeAsync(results);
console.log(output);
input.then(
function (x) {
var v=new Uint8Array(x);
console.log(v);
},
function () {
console.log("fail ");
});
I receive for the printout of the input:
Uint8Array [
129,
210,
132,
77,
...
I receive for the printout of the output:
Uint8Array [
210,
132,
77,
...

cbor.decodeAllSync with n arguments returns an array with n entries. So what you encode has an extra pair of [] around it.
> cbor.decodeAllSync(cbor.encode(1))
[ 1 ]
> cbor.decode(cbor.encode(1))
1

Related

Mongoose handle base64/ binary encode and decode

I'm struggling to wrap my head around this and I've read all the posts I can find on it, but still am not making sense of the results I'm getting. I'm using react-signature-canvas which produces the output into a base64 string. I then seem to be successfully saving this through Mongoose with:
let data = req.body.submittedSig.data;
let split = data.split(',');
let base64string = split[1];
const buffer = Buffer.from(base64string, 'base64');
//...//
submittedSig: {
data: buffer,
contentType: plan.submittedSig.contentType
},
this shows in the db as:
submittedSig
Object
data
BinData(0, 'iVBORw0KGgoAAAANSUhEUgAAAJYAAABsCAYAAACICEudAAANIElEQVR4Xu2dSwgsRxWGjaj4CKjgxpVzjYrowidowOAoxMcmKgqi…')
contentType
"image/png"
When trying to decode, I've used several approaches such as .toBase64() - https://www.mongodb.com/docs/atlas/app-services/functions/globals/#bson--binary-json- mongo function, but I get a 'not a function' error, and otherwise I've played with various combinations of Buffer.from(data, 'base64') and .toString('base64'). https://nodejs.org/api/buffer.html#static-method-bufferfromstring-encoding
const servicePlan = await ServicePlan.findOne({ _id: req.params.planId })
// let sig = Buffer.from(servicePlan.submittedSig.data, 'base64').toString('base64');
// sig = servicePlan.submittedSig.data.toString('base64');
sig = servicePlan.submittedSig.data.toBase64();
servicePlan.submittedSig.data = sig
console.log("sig plan: ", servicePlan)
res.send(servicePlan)
For any combination of the Buffer.from or .toString- whether used separetely or together, the console.logs the output as
data: new Binary(Buffer.from("6956424f5277304b ... 414141456c46546b5375516d4343", "hex"), 0),
and the return comes as:
"submittedSig": {
"data": {
"type": "Buffer",
"data": [
137,
80,
78,
71,
13,
10,
26,
10,
0,
0,
0,
13,
...
]
So as far as I can tell, the encoding takes it into binary, but all of my output is not decoding back to base64. Let alone, the end of the console.log of shows 'hex' which had me trying to convert the binary as if it was stored as a hex object, but that hasn't worked either. I'm sure its something simple that I just don't get with these, appreciate any guidance.

Array Set Length unequal to Sum of Array Distribution

I have a list of user ids like so: ["1111","5555","1111","8983",...]. I then compute the distribution of the frequency of the ids. But somehow adding the size of the distribution bins is smaller than the user set.
function histogram(List){
var d = {};
for(const x of List){
if (x in d){
d[x]+=1;
}
else{
d[x]=1;
}
}
return d
}
var featureuserids = f1_users.concat(f2_users,f3_users,f4_users)
var featureusers = [...new Set(featureuserids)];
const featurehist = histogram(Object.values(histogram(featureuserids)))
const n_featureusers = featureusers.length
Here is an example output.
Feature Users: 17379
Feature Hist: { '1': 16359, '2': 541, '3': 93, '4': 6 }
What is my mistake?
I have found the answer. One of my Lists (f1_users) had saved the ids as int, while the others were in string format. Therefore they were counted double in the set. After converting them all to string the issue was fixed.

nodejs convert decimal to hex(00-00) and reverse?

So I want to send a hex value to a service. The problem is that the service want this hex value in a specific format, 00-00, and also reversed.
For Example, when I want to tell the Service I want tag '1000':
1000 dec is 3E8 in hex. easy.
Now the service wants the format 03-E8.
Also the service reads from right to left so the final value would be E8-03.
Another example, '3' would be 03-00.
Edit:
I forgott to say that I dont need it as string, but as Uint8Array. So I would create the final result with new Uint8Array([232, 3]). (Eaquals E8-03 = 1000)
So the question in general is: How can I get a [232,3] from an input of 1000 or [3, 0] from 3?
Is there a build in methode or a pakage that already can do this convertion?
There's probably a much simpler way, but here is a simple solution.
Edit: If you need at least two pairs, you can change the first argument of padStart.
function dec2hexUi8Arr (n) {
const hex = (n).toString(16);
const len = hex.length;
const padLen = len + (len % 2);
const hexPad = hex.padStart(Math.max(padLen, 4), '0');
const pairs = hexPad.match(/../g).reverse().map(p => parseInt(p, 16));
const ui8Arr = new Uint8Array(pairs);
return ui8Arr;
}
const vals = [
1000,
3,
65536
].map(dec2hexUi8Arr);
console.log (vals);
I don't know any tool or package. I would do something like this:
const a = 1000;
const a0 = a % 256;
const a1 = Math.floor(a / 256);
const arr = new Uint8Array([a0, a1]);
console.log(arr);
const arrStr = []
arr.forEach((elem) => {
const str = elem.toString(16).toUpperCase();
if (str.length === 2) {
arrStr.push(str);
} else {
arrStr.push('0' + str)
}
});
console.log(arrStr.reverse().join('-'));
Output:
Uint8Array(2) [ 232, 3 ]
03-E8

Getting file name with second largest number in it when the numbers are same

I was trying to get file name in which is second largest number and it always outputs the file with largest number. What am I doing wrong?
Example: I have 3 file names in which are stored numbers like: 6 or 6 or 1 and it always outputs first file name with number 6 in it. I need to output the file name with second number 6.
const getSecondFileName = (pathToFolder) => {
const files = fs.readdirSync(pathToFolder);
const content = files.map(f => +fs.readFileSync(`${pathToFolder}/${f}`, 'UTF-8'));
const arrayCopy = [...content];
const secondLargestNum = arrayCopy.sort()[arrayCopy.length - 2]
const secondFileWithLargestInteger = files[content.indexOf(secondLargestNum)];
return secondFileWithLargestInteger;
}
Thank you for every answer.
since indexOf returns the first occurrence and you're firstLargestNum and secondLargestNum are the same (wich is a special case), let's handle it apart
const getSecondFileName = (pathToFolder) => {
let secondFileWithLargestInteger;
const files = fs.readdirSync(pathToFolder);
const arrLength = files.length;
const content = files.map(f => +fs.readFileSync(`${pathToFolder}/${f}`, 'UTF-8'));
const arrayCopy = [...content];
const sortedArray = arrayCopy.sort(function(a, b){
return a - b;
});;
const firstLargestNum = sortedArray[arrLength- 1];
const secondLargestNum = sortedArray[arrLength- 2];
if (firstLargestNum === secondLargestNum) {
const indexofFirst = content.indexOf(secondLargestNum);
// const indexofFirst = content.indexOf(firstLargestNum); same
secondFileWithLargestInteger = files[content.indexOf(secondLargestNum, (indexofFirst + 1))]
} else {
secondFileWithLargestInteger = files[content.indexOf(secondLargestNum)];
}
return secondFileWithLargestInteger;
}
I'm using a different method than yours here to sort, because element in your files are string.
var numbers = ['1', '5', '12', '3', '7', '15', '9'];
// Sorting the numbers array simply using the sort method
numbers.sort(); // Sorts numbers array
alert(numbers); // Outputs: 1,12,15,3,5,7,9
Sort method sorts the array elements alphabetically

convert buffer from database to string

I stored an buffer in database.
I have an buffer like this (from database):
{
data = (
76,
39,
65,
77,
66,
65,
83,
83,
65,
68,
79,
82
);
type = Buffer;
}
I'd like to convert it to string, but it is not working.
I tried with .toString('utf8');
console.log(buffer.toString('utf8');
I get :
{"type":"Buffer","data":[123,10,32,32,32,32,100,97,116,97,32,61,32,32,32,32,32,40,10,32,32,32,32,32,32,32,32,55,54,44,10,32,32,32,32,32,32,32,32,51,57,44,10,32,32,32,32,32,32,32,32,54,53,44,10,32,32,32,32,32,32,32,32,55,55,44,10,32,32,32,32,32,32,32,32,54,54,44,10,32,32,32,32,32,32,32,32,54,53,44,10,32,32,32,32,32,32,32,32,56,51,44,10,32,32,32,32,32,32,32,32,56,51,44,10,32,32,32,32,32,32,32,32,54,53,44,10,32,32,32,32,32,32,32,32,54,56,44,10,32,32,32,32,32,32,32,32,55,57,44,10,32,32,32,32,32,32,32,32,56,50,10,32,32,32,32,41,59,10,32,32,32,32,116,121,112,101,32,61,32,66,117,102,102,101,114,59,10,125]}
What's wrong in this? How can I get the value of this buffer?
Use the Buffer.from(array) syntax.
const data = [76,39,65,77,66,65,83,83,65,68,79,82];
const buf = Buffer.from(data)
const str = buf.toString();
console.log('str',str); // outputs L'AMBASSADOR

Resources