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.
Related
What is the methodology for generating a unique ID that minimizes the chance for an overlap?
for(let i = 0; i < <Arbitrary Limit>; i++)
generateID();
There are a few current solutions, but they are all roundabout ways of solving the problem.
Possible Solution 1:
Use a database to generate the new ID.
This does not work for me since I would like to do this in the frontend.
Possible Solution 2:
Use Math.random()*Math.floor(LIMIT), where LIMIT is a numeric value.
This does not work as minimizing the chance for overlap requires a large limit, and thus a massive ID. If working with hundreds of thousands of instances that need an ID, the chance increases greatly.
Possible Solution 3:
'_' + Math.random().toString(36).substr(2, 9);
This is close to working but I believe Math.random() is pseudo-random.
Possible Solution 4:
Date.now(). Date.getTime(), etc.
This does not work as generating [Date.now(), Date.now()] will cause the same ID. It arguably also needs a long ID to minimize overlap.
I do not require absolutely 0% chance of generating the same ID, I wish to minimize the chance as much as possible without:
Storing a count
Using 'other technology' (no database, no library, etc)
Making a massive ID
This preferrably should be scalabe, eg. This should work for 10 or 1000000 IDs.
Edit: Unique IDs generated locally and without need for communication across users of the frontend. Ex: A component needs to render many instances of the same class and needs a key to assign to it. Keys must be different and upon unmounting the component with its generated keys/instances is removed.
It seems you want to generate unique IDs entirely on the front-end and without relying on a backend at all or "storing a count". Then the solution depends, in part, on how many different users you expect will access your application's frontend during its lifetime, and the size of IDs depends on how much you're willing to tolerate the risk of collisions (assuming you're generating IDs at random); for that, see Birthday problem.
Then, depending on the size of IDs you choose, you generate the IDs at random using a cryptographic RNG (such as the function crypto.randomBytes), which is the closest available to "truly" random IDs.
On the other hand, if only few users will access your front end, but each one generates many unique IDs, then you can assign each user a unique value from a central database, because then each front-end computer can use that unique value as part of unique identifiers it generates and ensure that the identifiers are unique across the application without further contacting other computers or the central database.
Notice that there are other considerations as well: You should also consider whether just anyone should access the resource an ID identifies simply by knowing the ID (even without being logged in or authorized in some way). If not, then additional access control will be necessary.
For your purposes, you can try applying sequential IDs. If sequential IDs alone are not adequate, then you can try applying a reversible operation on sequential IDs. One example of this operation is technically called a "linear congruential generator with a power of 2 modulus", such as the ones described in the following pages:
How to sync a PRNG between C#/Unity and Python?
Algorithm or formula that can take an incrementing counter and make it appear uniquely random
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.
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.
I'm building a web app that sends a person an email every time the person is handed a document (a physical piece of paper). The email contains a link that allows the user to request for a document pick up. The link should contain the user's id and the document's id. Is there a safe way to generate this link? Is this a good practice or are there other ways to implement such a thing?
I was thinking of using a hashing algorithm on the link, is this a good approach?
I'm using expressjs for my server side.
Thanks
Use for example node-uuid to create a UUID and pass it on the link, then store on the database to which document the UUID is linked to.
This solves several problems:
an attacker cannot guess UUIDs
there is no information on the UUID that can be extracted
I don't think hashing would help in this case, as we just need a way to create a one time token that cannot be guessed.
Hashing, obviously, will not include the document and the user's ID. So it's a bit confusing whether you want secure obfuscation (in which case you would want to use a hash algorithm (salt it if you're paranoid) that then quickly checks whether there is a document with the same ID and generates a new one to avoid document-ID mismatch) or that user and document IDs be included (in which case creating a format that includes both and a brief, usually session-dependent, ID to prevent document-ID mismatch will be just perfect).
I want to generate unique number for each of my site users.
How can I achieve something like this using JavaScript?
P.S: I also want this unique number have information about users for example something like IP or concatenation something with IP.
Can I have user IP using JavaScript?how?
Generating a guaranteed unique number for every site user cannot be done purely at the browser. The only way to guarantee a unique number for every site user is to generate the unique number at the server and give that to the browser (either in the original page or via an ajax call or via a post/get).
If you want a statistically unlikely to be the same number that isn't 100% guaranteed, then you can use a time number plus a random number or a very, very long random number and have a statistically unlikely to be the same number, but not 100% guaranteed to be unique number.
There is no way that I'm aware of to get the IP address from pure client-side javascript without asking a server and, even if you could, because of proxies, NAT, firewalls, etc... IP numbers are not guaranteed to be unique or constant for a given user either. For example, all the users in my home all share the same outgoing IP address.