Search code examples
flutterdart

How to generate collision free integers from a 24 hex string


I am facing an issue where I receive a 24-character hexadecimal string (objectId) from an API, and I have a function that only accepts ints. How can I generate collision-free integers from this hexadecimal string?

I implemented the following code to convert the hex string into a collision free integer ID:

int generateUniqueIntId(String objectId) {
  String objectIdDigest = objectId.sha256Digest();
  BigInt bigIntHash =
      BigInt.parse(objectIdDigest.toString().substring(0, 16), radix: 16);
  BigInt originalId = BigInt.parse(objectId, radix: 16);
  BigInt combined = bigIntHash ^ originalId;
  return combined.toInt();
}

For example, given this sample objectId:

679f81e1c02ea904a2000000

My Current Problem:

No matter what the objectId is, I always get the following integer output: 9223372036854775807

What I Need:

I need the generated integers to be collision-free for each unique objectId. Specifically, for any given objectId, the generated integer should never be the same as the integer for another objectId.


Solution

  • This is nearly impossible.

    However, if you have any sort of control over the objectIds from the API then I can assume we are working within a controlled space from where the objectIds are generated and not any kind of universal objectId.

    In that case you can try this out, this just picks the first valid integer that can fit into dart's int max from the objectId.

    int generateUniqueIntId(String objectId) {
      BigInt originalId = BigInt.parse(objectId, radix: 16);
      String originalIdStr = originalId.toString();
      BigInt dartIntMax = (BigInt.one << 63) - BigInt.one;
      String maxIntStr = dartIntMax.toString();
      int length = maxIntStr.length;
      BigInt uniqueInt;
      do {
        uniqueInt = BigInt.parse(originalIdStr.substring(0, length));
        length--;
      } while (uniqueInt > dartIntMax);
      return uniqueInt.toInt();
    }