Skip to content

Instantly share code, notes, and snippets.

@YuzuRyo61
Last active April 13, 2022 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YuzuRyo61/2c1a301c90c250a76b3a10f89f1b345b to your computer and use it in GitHub Desktop.
Save YuzuRyo61/2c1a301c90c250a76b3a10f89f1b345b to your computer and use it in GitHub Desktop.
勢いだけで作ったID生成器
import time
import random
import datetime # 生成器では使用しない
class ByaccoID:
def __init__(
self,
timestamp: int,
random_seq: int,
):
if timestamp.bit_length() > 48:
self.timestamp = timestamp >> (timestamp.bit_length() - 48)
else:
self.timestamp = timestamp
if random_seq.bit_length() > 16:
self.random_seq = random_seq >> (random_seq.bit_length() - 16)
else:
self.random_seq = random_seq
def __str__(self) -> str:
s = self.timestamp << 16 | self.random_seq
return f"{s:0>16x}"
def get_unix_time(self) -> float:
return (self.timestamp << 13) * (10 ** -9)
def as_int(self) -> int:
return self.timestamp << 16 | self.random_seq
@classmethod
def generate(cls) -> "ByaccoID":
return cls(time.time_ns(), random.randint(0, 2 ** 16))
@classmethod
def from_str(cls, s: str) -> "ByaccoID":
i = int(s, 16)
return cls(i >> 16, i & 0xFFFF)
@classmethod
def from_int(cls, i: int) -> "ByaccoID":
return cls(i >> 16, i & 0xFFFF)
@classmethod
def zero(cls) -> "ByaccoID":
return cls(0, 0)
def __eq__(self, other) -> bool:
if not isinstance(other, ByaccoID):
return False
return self.timestamp == other.timestamp and self.random_seq == other.random_seq
def __lt__(self, other) -> bool:
if not isinstance(other, ByaccoID):
return False
if self.timestamp == other.timestamp:
return self.random_seq < other.random_seq
else:
return self.timestamp < other.timestamp
def __le__(self, other) -> bool:
if not isinstance(other, ByaccoID):
return False
return self.timestamp <= other.timestamp
def __gt__(self, other) -> bool:
if not isinstance(other, ByaccoID):
return False
if self.timestamp == other.timestamp:
return self.random_seq > other.random_seq
else:
return self.timestamp > other.timestamp
def __ge__(self, other) -> bool:
if not isinstance(other, ByaccoID):
return False
return self.timestamp >= other.timestamp
if __name__ == '__main__':
a = set()
count = 100
for _ in range(count):
bid = ByaccoID.generate()
a.add(str(bid))
print("{} {} -> {}".format(bid, bid.get_unix_time(), datetime.datetime.fromtimestamp(bid.get_unix_time())))
assert len(a) == count
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment