mirror of
https://github.com/exaloop/codon.git
synced 2025-06-03 15:03:52 +08:00
56 lines
1.2 KiB
Python
56 lines
1.2 KiB
Python
# Copyright (C) 2022-2025 Exaloop Inc. <https://exaloop.io>
|
|
|
|
from .seed import SeedSequence
|
|
|
|
def rotl(value: u64, rot: int):
|
|
return (value << u64(rot)) | (value >> u64((-rot) & 63))
|
|
|
|
class SFC64:
|
|
s0: u64
|
|
s1: u64
|
|
s2: u64
|
|
s3: u64
|
|
seed: SeedSequence
|
|
|
|
def __init__(self, s0: u64, s1: u64, s2: u64):
|
|
self.s0 = s0
|
|
self.s1 = s1
|
|
self.s2 = s2
|
|
self.s3 = u64(1)
|
|
|
|
for _ in range(12):
|
|
self.next64()
|
|
|
|
def __init__(self, seed):
|
|
if not isinstance(seed, SeedSequence):
|
|
self.__init__(SeedSequence(seed))
|
|
else:
|
|
val = seed.generate_state(3, u64)
|
|
self.__init__(val[0], val[1], val[2])
|
|
self.seed = seed
|
|
|
|
def __get_state__(self):
|
|
return (self.s0, self.s1, self.s2, self.s3)
|
|
|
|
def __set_state__(self, state):
|
|
s0, s1, s2, s3 = state
|
|
self.s0 = s0
|
|
self.s1 = s1
|
|
self.s2 = s2
|
|
self.s3 = s3
|
|
|
|
def next64(self):
|
|
s0 = self.s0
|
|
s1 = self.s1
|
|
s2 = self.s2
|
|
s3 = self.s3
|
|
|
|
tmp = s0 + s1 + s3
|
|
|
|
self.s0 = s1 ^ (s1 >> u64(11))
|
|
self.s1 = s2 + (s2 << u64(3))
|
|
self.s2 = rotl(s2, 24) + tmp
|
|
self.s3 += u64(1)
|
|
|
|
return tmp
|