How to generate unique number from string in node.js - javascript

I would like to generate a unique number from string. The string is a combination of username and password. I would like to generate a unique number id (not string) from this combination. I first md5 the combination and then convert it to number. The number length needs to be 10. Any suggestions?

It would be best if you can provide more details about the third-party you're trying to interface with, because this is a very odd request and it contains a fundamental flaw. You ask for the number to be unique, but you are allowing for only 10 decimal ("number id") digits, or ~10 billion possible values.
This sounds like an awful lot but it's really not. This gives you a hash of just over 33 bits. The simple hash collision probability calculator at http://davidjohnstone.net/pages/hash-collision-probability puts this at a 44% chance of a collision at just 100,000 entries. But that assumes full usage of all the available input characters. Since username and password combinations are almost always limited to alphabetic and numeric characters, the real collision chance is much worse at far fewer entries (can't be calculated without knowing the characters you allow for these fields - but it's bad).
NodeJS provides numerous crypto functions in the crypto module. A whole set of hashing functions is available, including the ideal-case SHA* options. These can be used to provide safe, irreversible hashes with astronomically collision probabilities.
If these options are not usable for you, I would suggest you have a fundamental design flaw. You're almost certainly mapping a user/pass combination to a userID in a remote system in a way that an attacker would find easy to compromise with a simple brute-force attack, given the high collision risk in your model.
If you are doing what I think you are doing, the "right" way to do this would be to have a simple database on a server somewhere. The user/pass would be assigned a unique ID in there, and it doesn't matter what this is - it could be an auto-increment ID field in a single MySQL table. The server would then contact this remote service with the ID value for any API calls necessary, and return the results to the user. This eliminates the security risk because the username/password are not actually hashed, just stored, and can be checked 100% on every call.
Never use a hash as a primary data value. It's a simplification, not a real value on its own.

Related

How to generate a referral link from an Hash code in nodejs

I have a system where each account of a user has a unique id, I can't user that id as a referral link because it contains dashes -.
I need to generate a unique referral code given that id, I thought about using a sha256 of that id.
The problem is that the sha256 is too long to be used as a referral but if I truncate it, the collision chances increase.
Is there any way to generate a referral link given an id?
this is the format id: 04v23533-680d-1107-j4h1-1c32343c1004
If your user IDs are random and unique, then you can't use them to generate shorter IDs without collisions (because you're effectively trying to compress random data).
Realistically though, are collisions a concern? If you have 500 users a a truncated hash has a one in 100 billion chance of colliding, is that really a problem? Depends how many users you have, and how long your codes can be.
But referral links don't need to be secret, they just need to be unique. So at the simplest level you could just generate sequential integers and use those for the IDs? Sure, you could guess other valid referral IDs, but who cares?
If you want them to be a bit more complex, you could generate random strings, and check them against the current list of IDs in the database to make sure that they're unique. But this might slow down once you have millions of users.

How can I predict Math.random results?

How can I predict the results from a roulette gaming website csgopolygon.com, given that it is calling Math.random and Math.floor?
Your hunch that it is, in theory, possible to predict the results of Math.random is correct. This is why, if you ever want to build a gaming/gambling application, you should make sure to use a cryptographically secure pseudo-random number generator. If they are using such, then forget about it.
If however you are correct and they are using System.time as the seed to the standard Random generator that comes with Java, there might be a way. It would involve generating millions of numbers sequences with millions of numbers in each sequence, based on seeds corresponding to (future) timestamps, then observing the actual random numbers generated by the website and trying to find the specific sequence among the millions you generated beforehand. If you have a match, you found the seed. And if you have the seed and know where in the sequence they are, you could then theoretically predict the next numbers.
Problems with this approach:
You need to know the exact algorithm they are using, so you can make sure you are using the same
It would take huge amounts of processing power to generate all the sequences
It would take huge amounts of storage to store them
It would take huge amounts of processing power to search the observed sequence among the stored sequences
You don't have the full picture. Even if you found the right seed and position in that seed's sequence, you still need to predict the next number that you will get, but as it's a multiplayer site (I assume), they might be giving that number to another player.
In other answers it is said that predicting the results of Math.random is impossible. This is incorrect. Math.random is actually very predictable, once you know the seed and the iteration (how many numbers were generated since the seed was set). I actually once built a game that generated random levels. I was messing with the seed and found that if I always set the same seed, I would always get the same levels. Which was cool because my game had infinite levels, but level 27 (for example) always looked exactly the same.
However,
They are not using Java. Check out the 'Provably Fair' link at the top. They discuss how you can verify past rolls yourself by executing PHP code.
These guys are smart. They are publishing the old seeds once they dismiss it. This allows you (using the predictable behavior of pseudo-random number generators) to re-generate all rolls and verify that they never tampered with them.
Basically, you want to find the seed that is currently in use... However, point 5 I mentioned above still holds: you don't have the full picture, so how would you predict what roll you would be getting? Apart from that, finding the seed will prove near impossible. These guys know cryptography, so you can bet they are using a secure random number generator.
You can't, and you probably shouldn't develop a gambling addiction as a 16-year-old. That said, even if you could, that site isn't using JavaScript to generate a number, but a server-side language like PHP or ASP.NET.

Generating a short, pseudo-random verifiable alpha numeric code

I have a situation where I need to generate short pseudo-random alphanumeric tokens which are unique, verifiable, and easily type-able by a human. These will be generated from a web app. The tokens don't need to be highly secure - they're used in a silly web game to claim a silly prize. For various reasons, the client wants these tokens to be human-readable and handled via email. This is non-negotiable (I know... but this is how it has to be for reasons beyond my control).
In other words, let's say we get the code "ABCDE12345"
There has to be a way to say "ABCDE12345" is "valid". For example: maybe two or three characters at the start run through an algorithm I write will generate the right sequence of remaining characters. E.g., f("AB")==="CDE12345"
Two people playing the game shouldn't be likely to generate the same token. In my mind, I'd be happy to use the current time in millis + game-character name & score to seed a home-made RNG. (which is to say, NOT use Math.random, since this is a web app). This would seed the two or three character sequence mentioned above.
Am I missing anything? I'm not looking for a concrete algorithm but rather your suggestions. Anything I'm missing?
If you think your token is comparable to an authenticated message saying "give this person a prize" you could look at https://en.wikipedia.org/wiki/Hash-based_message_authentication_code, recoding as necessary with e.g. https://en.wikipedia.org/wiki/Base64 to make the thing printable. Of course, HMAC uses a secret key which you will have to KEEP secret. A public key signature system would not require that you keep the key secret, but I would expect the signature to be longer, and I expect that it is already too long for you if you want non-trivial security.
A simple solution (and easy to hack) would be to generate a meaningful term (one way to achieve such is choose a random article from wikipedia), encrypt it with a pre-known password, and take the least significant x bits.
Now, the key you generate is word-<x bits as a number>.
This is easily verifiable by machine, simply re-encode the word and check if the bits fit, and offers a simple tradeoff of readability vs security (bigger x -> less readable, harder to fake).
Main problem with this approach though, is assuming your game is not communicating with any server, you will need to deploy the preshared secret somehow to your clients, and they will be able to reverse engineer it.

What are the uniqueness guarantees of names generated with Firebase's push()/childByAutoID?

I'd like to use Firebase to make publicly-readable data whose location is difficult to guess. So, to give someone access to the data stored in "element [element ID = X]", I'd like to just send them "X", instead of sending them "X" along with a security token crafted to give them access to the element. Firebase's push() and childByAutoID seem like a natural fit: I can grant public read access to all individual elements, but deny public listing. My code will be blissfully free of token and random number generation. The automatically generated ID is supposed to be unique, and thus should be difficult to guess.
From looking at Firebase.js, it appears the first 8 characters of the automatically generated ID are based on the current timestamp, and the next 12 characters are randomly generated using Math.random(). I assume that the iOS framework does the same thing, and although I can't see the code, the library links to both SecRandomCopyBytes and arc4random.
For my purposes, this looks good enough, but has anyone seen guidance from Firebase on whether we can count on this behavior? I would hate to build code that assumes these names are relatively strong random strings and then have that assumption violated when I upgraded to a newer version of Firebase.
The purpose of the auto-generated IDs provided by Firebase is to allow the developer to create a chronologically ordered list in a distributed manner. It relies on Math.random and the timestamp to generate an ID unique to that client.
However, if you're going to use the auto IDs as security keys, it may not be the best idea depending on how secure you want your system to be. Math.random is not a cryptographically secure random number generator and since push() relies on it, the IDs generated by it aren't either.
The general concept of giving a user access to some data in Firebase if they know the key is a good one though. We have an example of using this type of security rule, but instead of using push IDs, we use a SHA-256 hash of the content itself (in this particular case, they are images). Hashing the content to generate the keys is more secure than relying on push() IDs.

Match Phone Numbers Regardless of Formatting

I've written a query for Mongo to search for a phone number. The gotcha is the phone entry is a String rather than a Number. At first I thought it was working fine, however now I realize that if the query isn't formatted correctly it will not match.
So I guess my question is what's the easiest way of matching a phone number regardless of formatting?
Worst case scenario I use a $where statement and check equality by removing numbers from both the values and doing a regex match on that. Just wondering if there is a more optimal way of doing this?
I would store the phone numbers normalized (e.g. either stripped of non numeric chars, or formatted in a standard format) in the DB in the first place, since they are not already normalized, doing it on the fly for each search request will be expensive, so if you don't have too many entries already (e.g. if this is still all in development), a script that will normalize all entries in one shot (or in several batches during off peek hours if you have a production system) will be possible.
Then your where clause will just normalize the input, and then the search will be much easier.
Same goes for addresses by the way, you have to normalize the data to perform good search, or you'll have to develop some fuzzy matching algorithm, that is simply going to be slower. (and might take you more time than you think)

Categories