-1

I have two data objects, the user and a record.

The user should have a unique id, the record should have one too. The record has an owner, the user, each record contains the userId. So I created a simple Id generator

$( document ).ready(function() {
    $("#btn").click(function(){ 
      createId();
    });
});

var myIds = [];

function createId(){ // Create new ID and push it to the ID collection
  var id = generateNewId();
  myIds.push(id);
  console.log("The current id is: ");
  console.log(id);
  console.log("The array contains: ");
  console.log(myIds);
}

function generateNewId(){ // Check for existing IDs
  var newId = getNewId();
  if($.inArray(newId, myIds) > -1){ // Does it already exist?
    newId = generateNewId(); // 
  } 
  else{
    return newId;
  }
}

function getNewId(){ // ID generator
    var possibleChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    var serialLength = 20;
    var generatedId = '';

    for (var i = 0; i < serialLength; i++) {
      var randomNumber = Math.floor(Math.random() * possibleChars.length);
      generatedId += possibleChars.substring(randomNumber, randomNumber + 1);
    }

    return generatedId;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="btn">Add new ID</button>

So this generator works fine for both ids. But what is the correct way in generating user ids?

Is there a way to generate a unique user id when creating an account in country ? at the time ? by user ?

The record object has an ID too, is there a way to make it contain parts of its owner, the user id?

The shown generator is able to create a large range of possible ids. But what happens, when there is no possibility anymore? That's why I want a "better" way of creating IDs.

peterHasemann
  • 1,550
  • 4
  • 24
  • 56
  • How about UUID's? – RubbelDieKatz Sep 06 '17 at 08:22
  • `But what is the correct way in generating user ids` Whatever way is most appropriate for your use case. We can't really help with that, and it's off-topic for SO anyway. `But what happens, when there is no possibility anymore?` You have a possible 98,924,644,154,748,233,299,110,042,009,600,000 permutations. I don't think you're going to run out. Even collisions shouldn't be an issue. That being said, UUID/GUIDs are a more standard approach: https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript – Rory McCrossan Sep 06 '17 at 08:24

1 Answers1

2

If you're using node, you can use uuid: https://www.npmjs.com/package/uuid This package allows you to create universal unique IDs.

On browser side, your best bet is implement a simple function that gets the job done. Yours is not bad but you risk collision. I would use the one from npm uuidv4 which is more evolved:

function uuidv4() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

const uuidv4es8 = () =>
  'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    const r = Math.random() * 16 | 0
    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16)
  });

//EDIT customize it if you want:
const uuidv4es8WithoutDash = () => 
  'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
    const r = Math.random() * 16 | 0
    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16)
  });

const uuidFactory = 
  (myFormat,encodingBase) => 
   () =>
     myFormat.replace(/[a-zA-Z]/g, c => (Math.random() *  encodingBase| 0).toString(encodingBase))

console.log(uuidv4())
console.log(uuidv4())
console.log(uuidv4())
console.log(uuidv4())
console.log(uuidv4())

console.log(uuidv4es8())

//EDIT: delete the dash if you want !
console.log(uuidv4es8WithoutDash())

//Create a function that returns uuid as you want them:
let myUuidv4es8 = uuidFactory('1-xxxxx-xxxxx',23)
console.log(myUuidv4es8())
console.log(myUuidv4es8())

myUuidv4es8 = uuidFactory('x-xx-xxx-xxxxx',6)
console.log(myUuidv4es8())
console.log(myUuidv4es8())
//australian phone number:
myUuidv4es8 = uuidFactory('61-xxx-xxx-xxx',10)
console.log(myUuidv4es8())
console.log(myUuidv4es8())
Théophile Pace
  • 826
  • 5
  • 14
  • Note that if you generate these ID's on the client's side and send them to the server, you allow the client to tamper with it. Sanitize everything. There is a huge SQL injection risk. – RubbelDieKatz Sep 06 '17 at 08:31
  • 1
    So using `uuidv4es8()` is a better one than using `uuidv4()` ? And there is no problem using `xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx` instead of `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` ? – peterHasemann Sep 06 '17 at 08:39
  • 1
    @RubbelDieKatz I've never said it was a good idea ;) Seriously, I don't know the use case for this function. Maybe there is no other way to generate an ID and it is not critical. However, I agree, you should ask an API to generate it and the API would be in charge of inserting it in a DB (at least, I would do it that way). – Théophile Pace Sep 06 '17 at 08:39
  • 1
    @peterHasemann no, this is exactly the same function, I am trying to use es8 as much as possible these days. I just feel like it's cleaner? You use the one you find the easier to read :) – Théophile Pace Sep 06 '17 at 08:41
  • The uuid library is going to give you something like xxx-xxxx-xxxx-xxxx so I gave the same for the online function. It is just a common format. once again, use the one you prefer! – Théophile Pace Sep 06 '17 at 08:46
  • I edited my answer, as you can see you could use whatever format you like with the last function. However, I would recommend the uuidv4 format to be compatible with other software. Using NPM library will allow you to stay up to date without doing anything yourself. – Théophile Pace Sep 06 '17 at 08:54