How to clone a QRCode image with given content text? - node.js

I have a QRCode image and it's content: P01 V0N S0000000
I tried to regenerate this image with different matchPattern using node-qrcode:
const $qr = require('qrcode')
const text = 'P01 V0N S0000000'
for (let i = 0; i < 8; i++) {
let path = `P01V0NS0000000-${i}.png`
const opt = {
maskPattern: i
}
$qr.toFile(path, text, opt, function (err) {
if (err) {
console.log(err)
} else {
console.log(opt)
}
})
}
but none of generated image has the same pattern as the target:
I also tried with different version paramter, but all version>1 will generate a much dense pattern.
Is this QRCode image generated with some kind of salt to make hard to replicate?

No need to try with another version as your first image clearly is a version 1 (21x21). Instead, it might be the format encoding (given the set of chars, the app might use alphanumeric and your original might well be byte for example)
As per the link you provided, I'd recommand reading this section about modes and try either with:
mode: 'alphanumeric'
or with:
mode: 'byte'
to see if any of those match your original code.
Another parameter that can change the aspect of the QR-code is the error correction level. I'd guess by default node-qrcode uses the highest level possible given version 1, and your original might use a lower one.
With those params, you have a set of 8(maskPattern)*2(mode)*4(errorCorrectionLevel) = 64 possible QR-codes with the same data inside, so maybe one of them will match!
Edit
As your data is 16 characters long, the scope is reduced as error correction level can only have the following values (source):
L,M,Q for alphanumeric mode
L for byte mode
Therefore, you have (3+1)*8 = 32 possible resulting images.

Related

Is it possible to store Cytoscape.js layout data directly to a file format in app/web server and re-launch the same layout to minimize re-computation?

Some of the cytoscape layout is randomize where the position is not fix every time we launch it. I understand from multiple stack overflow questions where we can save the layout data (i.e. including its position x and y) into browser local storage or session storage so that we can display the same layout using the same data.
However, the problem with local storage or session storage is good for one users. But, imagine if there are thousands of users using the same app, the server will undergo mass computation for each user to store respective data to individual browsers. Can we save the data into a file format directly into app/web server so that 1000 users will see the same layout and this reduces the computation of different data set as well.
Thank you. Would like to know the possibility to convert data into a file and store in the web/app server.
Yes, you can store position data. Actually, there are 2 options in my mind.
Use cy.json(). You can store the elements as JSON like JSON.stringify(cy.json().elements) and then save this JSON string.
cy.json().elements is something like the below image
You can restore this data easily like cy.json({elements: JSON.parse(jsonStr));
As you could see cy.json().elements is a bit big thing. Position data is just a small object like {x: 0, y: 0}. Additional to position it contains many other data. So if you only need to restore the positions, you could store them manually easily with a code like below. You can use ele.id and node.position() functions.
function storePositions() {
const nodes = cy.nodes();
const nodePositions = {};
for (let i = 0; i < nodes.length; i++) {
nodePositions[nodes[i].id()] = nodes[i].position();
}
return nodePositions;
}
You can also restore node positions easily. You can use getElementById and node.position() functions.
function restorePositions(nodePositions) {
const nodes = cy.nodes();
const nodePositions = {};
for (let k in nodePositions) {
const node = cy.getElementById(k);
if (node && node.length > 0) {
node.position(nodePositions[k]);
}
}
return nodePositions;
}

Searching an array of strings in a file

I have a text file say, testFile.txt and an array of strings to be searched in the file as say, ['year', 'weather', 'USD 34235.00', 'sportsman', 'ಕನ್ನಡ']. I can break the file into tokens with NodeJS natural and maybe, create a large array (~100-200x the number of entries in the string array) out of it. Then, sort both the arrays and start the search. Or, use lodash directly?
A Found result is when at least one string from the search string array is found in the text file; else, it should be considered as NotFound.
What are some of the options to implement such a search?
I could suggest using Set for large array of tokens, then iterate through the search terms array, check if the tokens set has one of those terms. If the terms array is also large, you could considers using Set for that (MDN docs for Set)
You could see the performance comparision between array and set in context of large number of elements, from this comment
Below is the demo snippet
const tokens1 = ['ಕನ್ನಡ', 'asdasd', 'zxczxc', 'sadasd', 'wqeqweqwe', 'xzczxc']
const tokens2 = ['xzczcxz', 'asdqwdaxcxzc', 'asdxzcxzc', 'wqeqwe', 'zxczcxzxcasd']
const terms = ['year', 'weather', 'USD 34235.00', 'sportsman', 'ಕನ್ನಡ']
const set1 = new Set(tokens1)
const set2 = new Set(tokens2)
const find = (tokensSet, termsArray) => {
for (const term of termsArray) {
if (tokensSet.has(term)) {
return 'Found'
}
}
return 'Not Found'
}
console.log(find(set1, terms))
console.log(find(set2, terms))

Short user-friendly ID for mongo

I am creating a real time stock trading system and would like to provider the user with a human readible, user friendly way to refer to their orders. For example the ID should be like 8 characters long and only contain upper case characters e.g. Z9CFL8BA. For obvious reasons the id needs to be unique in the system.
I am using MongoDB as the backend database and have evaluated the following projects which do not meet my requirements.
hashids.org - this looks good but it generates ids which are too long:
var mongoId = '507f191e810c19729de860ea';
var id = hashids.encodeHex(mongoId);
console.log(id)
which results in: 1E6Y3Y4D7RGYHQ7Z3XVM4NNM
github.com/dylang/shortid - this requires that you specify a 64 character alphabet, and as mentioned I only want to use uppercase characters.
I understand that the only way to achieve what I am looking for may well be by generating random codes that meet my requirements and then checking the database for collisions. If this is the case, what would be the most efficient way to do this in a nodejs / mongodb environment?
You're attempting to convert a base-16 (hexadecimal) to base-36 (26 characters in alphabet plus 10 numbers). A simple way might be to simply use parseInt's radix parameter to parse the hexadecimal id, and then call .toString(36) to convert that into base-36. Which would turn "507f191e810c19729de860ea" into "VDFGUZEA49X1V50356", reducing the length from 24 to 18 characters.
function toBase36(id) {
var half = Math.floor(id.length / 2);
var first = id.slice(0, half);
var second = id.slice(half);
return parseInt(first, 16).toString(36).toUpperCase()
+ parseInt(second, 16).toString(36).toUpperCase();
}
function toBase36(id) {
var half = Math.floor(id.length / 2);
var first = id.slice(0, half);
var second = id.slice(half);
return parseInt(first, 16).toString(36).toUpperCase()
+ parseInt(second, 16).toString(36).toUpperCase();
}
// Ignore everything below (for demo only)
function convert(e){ if (e.target.value.length % 2 === 0) base36.value = toBase36(e.target.value) }
var base36 = document.getElementById('base36');
var hex = document.getElementById('hex');
document.getElementById('hex').addEventListener('input', convert, false);
convert({ target: { value: hex.value } });
input { font-family: monospace; width: 15em; }
<input id="hex" value="507f191e810c19729de860ea">
<input id="base36" readonly>
I understand that the only way to achieve what I am looking for may well be by generating random codes that meet my requirements and then checking the database for collisions. If this is the case, what would be the most efficient way to do this in a nodejs / mongodb environment?
Given your description, you use 8 chars in the range [0-9A-Z] as "id". That is 36⁸ combinations (≈ 2.8211099E12). Assuming your trading system does not gain insanely huge popularity in the short to mid term, the chances of collision are rather low.
So you can take an optimistic approach, generating a random id with something along the lines of the code below (as noticed by #idbehold in a comment, be warn that Math.random is probably not random enough and so might increase the chances of collision -- if you go that way, maybe you should investigate a better random generator [1])
> rid = Math.floor(Math.random()*Math.pow(36, 8))
> rid.toString(36).toUpperCase()
30W13SW
Then, using a proper unique index on that field, you only have to loop, regenerating a new random ID until there is no collision when trying to insert a new transaction. As the chances of collision are relatively small, this should terminate. And most of the time this will insert the new document on first iteration as there was no collision.
If I'm not too wrong, assuming 10 billion of transactions, you still have only 0.3% chance of collision on first turn, and a little bit more than 0.001% on the second turn
[1] On node, you might prefer using crypto.pseudoRandomBytes to generate your random id. You might build something around that, maybe:
> b = crypto.pseudoRandomBytes(6)
<SlowBuffer d3 9a 19 fe 08 e2>
> rid = b.readUInt32BE(0)*65536 + b.readUInt16BE(4)
232658814503138
> rid.toString(36).substr(0,8).toUpperCase()
'2AGXZF2Z'

How to generate short unique names for uploaded files in nodejs

I need to name uploaded files by short unique identifier like nYrnfYEv a4vhAoFG hwX6aOr7. How could I ensure uniqueness of files?
Update: shortid is deprecated. Use Nano ID instead. The answer below applies to Nano ID as well.
(Posting my comments as answer, with responses to your concerns)
You may want to check out the shortid NPM module, which generates short ids (shockingly, I know :) ) similar to the ones you were posting as example. The result is configurable, but by default it's a string between 7 and 14 characters (length is random too), all URL-friendly (A-Za-z0-9\_\- in a regex).
To answer your (and other posters') concerns:
Unless your server has a true random number generator (highly unlikely), every solution will use a PRNG (Pseudo-Random Number Generator). shortid uses Node.js crypto module to generate PRNG numbers, however, which is a much better generator than Math.random()
shortid's are not sequential, which makes it even harder to guess them
While shortid's are not guaranteed to be unique, the likelihood of a collision is extremely small. Unless you generate billions of entries per year, you could safely assume that a collision will never happen.
For most cases, relying on probability to trust that collisions won't happen is enough. If your data is too important to risk even that tiny amount, you could make the shortid basically 100% unique by just prepending a timestamp to it. As an additional benefit, the file names will be harder to guess too. (Note: I wrote "basically 100% unique" because you could still, in theory, have a collision if two items are generated in the same timestamp, i.e. the same second. However, I would never be concerned of this. To have a real 100% certainty your only option is to run a check against a database or the filesystem, but that requires more resources.)
The reason why shortid doesn't do that by itself is because for most applications the likelihood of a collision is too small to be a concern, and it's more important to have the shortest possible ids.
One option could be to generate unique identifiers (UUID) and rename the file(s) accordingly.
Have a look at the kelektiv/node-uuid npm module.
EXAMPLE:
$ npm install uuid
...then in your JavaScript file:
const uuidv4 = require('uuid/v4'); // I chose v4 ‒ you can select others
var filename = uuidv4(); // '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
Any time you execute uuidv4() you'll get a very-fresh-new-one.
NOTICE: There are other choices/types of UUIDs. Read the module's documentation to familiarize with those.
Very simple code. produce a filename almost unique
or if that's not enough you check if the file exists
function getRandomFileName() {
var timestamp = new Date().toISOString().replace(/[-:.]/g,"");
var random = ("" + Math.random()).substring(2, 8);
var random_number = timestamp+random;
return random_number;
}
export default generateRandom = () => Math.random().toString(36).substring(2, 15) + Math.random().toString(23).substring(2, 5);
As simple as that!
function uniqueFileName( filePath, stub)
{
let id = 0;
let test = path.join(filePath, stub + id++);
while (fs.existsSync(test))
{
test = path.join(filePath, stub + id++);
}
return test;
}
I think you might be confused about true-random and pseudo-random.
Pseudo-random strings 'typically exhibit stastical randomness while being generated by an entirely deterministic casual process'. What this means is, if you are using these random values as entropy in a cryptographic application, you do not want to use a pseudo-random generator.
For your use, however, I believe it will be fine - just check for potential (highly unlikely) clashes.
All you are wanting to do is create a random string - not ensure it is 100% secure and completely random.
Try following snippet:-
function getRandomSalt() {
var milliseconds = new Date().getTime();
var timestamp = (milliseconds.toString()).substring(9, 13)
var random = ("" + Math.random()).substring(2, 8);
var random_number = timestamp+random; // string will be unique because timestamp never repeat itself
var random_string = base64_encode(random_number).substring(2, 8); // you can set size here of return string
var return_string = '';
var Exp = /((^[0-9]+[a-z]+)|(^[a-z]+[0-9]+))+[0-9a-z]+$/i;
if (random_string.match(Exp)) { //check here whether string is alphanumeric or not
return_string = random_string;
} else {
return getRandomSalt(); // call recursivley again
}
return return_string;
}
File name might have an alphanumeric name with uniqueness according to your requirement. Unique name based on the concept of timestamp of current time because current time never repeat itself in future and to make it strong i have applied a base64encode which will be convert it into alphanumeric.
var file = req.files.profile_image;
var tmp_path = file.path;
var fileName = file.name;
var file_ext = fileName.substr((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1);
var newFileName = getRandomSalt() + '.' + file_ext;
Thanks

Searching the Registry for a key - JScript

Is there a way to search the Registry for a specific key using Windows Scripting Host?
I'm using JavaScript (Jscript/VBScript?) to do so, and the msdn Library doesn't mention any such method: http://msdn.microsoft.com/en-us/library/2x3w20xf(v=VS.85).aspx
Thanks,
So here's an update to the problem:
The problem is a bit more complicated than a direct registry search. I have to look through the installed products on a windows box, to find a specific product entry that i want to delete. The registry path is defined as:
HKEY_LOCAL_MACHINE\Software\Microsoft...\Products.
Within the Products key, the installed products are listed, but their keys are defined as hash codes. Within the product keys are other keys with defined names and defined values. I want to be able to search on the latter keys and values. How can I do that, by-passing the unknown hash codes?
For example, I need to find a product with DisplayVersion key = 1.0.0. The path to that key is:
HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\Products\A949EBE4EED5FD113A0CB40EED7D0258\InstallProperties\DisplayVersion.
How can I either pick up, or avoid writing, the product key: A949EBE4EED5FD113A0CB40EED7D0258 ??
Assuming you're using JScript via the Windows Scripting Host (and not JavaScript from a browser) you can get the value of a specific key using the WScript.RegRead method:
// MyScript.js
var key = 'HKEY_CURRENT_USER\\SessionInformation\\ProgramCount'
, wsh = WScript.CreateObject('WScript.Shell')
, val = wsh.RegRead(key);
WScript.Echo('You are currently running ' + val + ' programs.');
If you actually need to search for a key or value based on some conditions rather than a known registry key then you can to implement your own recursive search algorithm where registry values of type "REG_SZ" are leaf nodes.
As an exercise to get more familiar with JScript on the Windows Scripting Host, I've made a small interface to the registry that does exactly this. The example included in the project shows how to perform such a registry search in a WSF script:
<job id="FindDisplayVersions">
<script language="jscript" src="../registry.js"/>
<script language="jscript">
// Search the registry and gather 20 DisplayVersion values.
var reg = new Registry()
, rootKey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products'
, keyRegex = /Products\\(.*?)\\InstallProperties\\DisplayVersion$/
, valRegex = /^1\./
, maxResults = 20
, uids = [];
reg.find(rootKey, function(path, value) {
var keyMatch = keyRegex.exec(path);
if (keyMatch) {
if (valRegex.exec(value)) {
uids.push(keyMatch[1] + '\t=\t' + value);
if (uids.length >= maxResults) { return false; } // Stop searching
}
}
return true; // Keep searching.
});
WScript.Echo(uids.join("\n"));
</script>
</job>
Note that, as #Robert Harvey points out, this could take a really long time if the root key is too deeply connected. Simple testing takes only a few seconds on the key I chose but your mileage may vary; of course, no warranty or fitness for a purpose, don't blame me if your computer blows up.
http://code.google.com/p/jslibs/
if you don't find it there, you have to implement it yourself

Resources