Created
September 26, 2021 06:31
-
-
Save LiosK/af9ba49a7e20d10f8611c1b739b08f0f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import datetime | |
from secrets import randbits | |
from typing import Tuple | |
# In general, the layered approach demonstrates much better collision resistance than | |
# the naive approach when the per-second randomness field is sufficiently large to | |
# accommodate a possible number of concurrent generators. Otherwise, the layered | |
# approach tends to cause burst collisions when the per-second randomness collides. | |
LEN_PER_SEC = 16 | |
LEN_PER_GEN = 4 | |
N_GENERATOR = 8 | |
Element = Tuple[int, int] | |
class Generator: | |
def __init__(self) -> None: | |
self.ts_sec = 0 | |
self.rand_sec = 0 | |
def generate(self, ts_now: int) -> Tuple[Element, Element]: | |
if ts_now - self.ts_sec > 1000: | |
self.ts_sec = ts_now | |
self.rand_sec = randbits(LEN_PER_SEC) | |
per_gen = randbits(LEN_PER_GEN) | |
naive = (randbits(LEN_PER_SEC), per_gen) | |
layered = (self.rand_sec, per_gen) | |
return (naive, layered) | |
def main() -> None: | |
generators = [Generator() for _ in range(N_GENERATOR)] | |
n_col = 0 | |
l_col = 0 | |
while True: | |
# This emulates a situation where multiple generators generate IDs with the same | |
# timestamp and counter. | |
n_set = set() | |
l_set = set() | |
ts_now = int(datetime.now().timestamp() * 1000) | |
for g in generators: | |
(n, l) = g.generate(ts_now) | |
if n in n_set: | |
n_col += 1 | |
print(f"Collision detected: naive: {n_col}, layered: {l_col}") | |
else: | |
n_set.add(n) | |
if l in l_set: | |
l_col += 1 | |
print(f"Collision detected: naive: {n_col}, layered: {l_col}") | |
else: | |
l_set.add(l) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment