snapshot before regression test

This commit is contained in:
t
2026-07-18 19:25:40 +08:00
commit 796222a300
2295 changed files with 206453 additions and 0 deletions

379
includes/vrandom.py Normal file
View File

@@ -0,0 +1,379 @@
# vrandom - 硬件随机数生成库
# 基于 x86 RDRAND / RDSEED 指令,使用内嵌汇编实现
import t, c
import vipermath
# 重试次数限制RDRAND 通常不需要重试RDSEED 可能需要)
RDRAND_RETRY_LIMIT: t.CDefine = 10
RDSEED_RETRY_LIMIT: t.CDefine = 100
# ============================================================
# RDRAND - 硬件随机数(伪随机数发生器输出)
# ============================================================
def rdrand16() -> t.CUInt16T:
val: t.CUInt32T = 0
c.Asm(f"rdrand {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC])
return t.CUInt16T(val)
def rdrand32() -> t.CUInt32T:
val: t.CUInt32T = 0
c.Asm(f"rdrand {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC])
return val
def rdrand64() -> t.CUInt64T:
val: t.CUInt64T = 0
c.Asm(f"rdrand {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC])
return val
# ============================================================
# RDSEED - 硬件随机种子(熵源直接输出)
# ============================================================
def rdseed16() -> t.CUInt16T:
val: t.CUInt32T = 0
c.Asm(f"rdseed {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC])
return t.CUInt16T(val)
def rdseed32() -> t.CUInt32T:
val: t.CUInt32T = 0
c.Asm(f"rdseed {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC])
return val
def rdseed64() -> t.CUInt64T:
val: t.CUInt64T = 0
c.Asm(f"rdseed {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC])
return val
# ============================================================
# Step 版本(带成功标志,匹配 GCC builtin 接口)
# 返回 1 表示成功0 表示失败;随机值写入 *p
# ============================================================
def rdrand16_step(p: t.CUInt16T | t.CPtr) -> t.CInt:
val: t.CUInt32T = 0
ok: t.CUInt32T = 0
c.Asm(f"""rdrand {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}
setc al
movzx {c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)}, al""",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG), c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC, t.ASM_DESCR.CLOBBER_AL])
p[0] = t.CUInt16T(val)
return t.CInt(ok)
def rdrand32_step(p: t.CUInt32T | t.CPtr) -> t.CInt:
val: t.CUInt32T = 0
ok: t.CUInt32T = 0
c.Asm(f"""rdrand {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}
setc al
movzx {c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)}, al""",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG), c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC, t.ASM_DESCR.CLOBBER_AL])
p[0] = val
return t.CInt(ok)
def rdrand64_step(p: t.CUInt64T | t.CPtr) -> t.CInt:
val: t.CUInt64T = 0
ok: t.CUInt32T = 0
c.Asm(f"""rdrand {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}
setc al
movzx {c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)}, al""",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG), c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC, t.ASM_DESCR.CLOBBER_AL])
p[0] = val
return t.CInt(ok)
def rdseed16_step(p: t.CUInt16T | t.CPtr) -> t.CInt:
val: t.CUInt32T = 0
ok: t.CUInt32T = 0
c.Asm(f"""rdseed {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}
setc al
movzx {c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)}, al""",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG), c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC, t.ASM_DESCR.CLOBBER_AL])
p[0] = t.CUInt16T(val)
return t.CInt(ok)
def rdseed32_step(p: t.CUInt32T | t.CPtr) -> t.CInt:
val: t.CUInt32T = 0
ok: t.CUInt32T = 0
c.Asm(f"""rdseed {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}
setc al
movzx {c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)}, al""",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG), c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC, t.ASM_DESCR.CLOBBER_AL])
p[0] = val
return t.CInt(ok)
def rdseed64_step(p: t.CUInt64T | t.CPtr) -> t.CInt:
val: t.CUInt64T = 0
ok: t.CUInt32T = 0
c.Asm(f"""rdseed {c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG)}
setc al
movzx {c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)}, al""",
out=[c.AsmOut(val, t.ASM_DESCR.OUTPUT_REG), c.AsmOut(ok, t.ASM_DESCR.OUTPUT_REG)],
op=[t.ASM_DESCR.CLOBBER_CC, t.ASM_DESCR.CLOBBER_AL])
p[0] = val
return t.CInt(ok)
# ============================================================
# 带重试的便捷接口(自动重试直到成功或达到上限)
# ============================================================
def random_u16() -> t.CUInt16T:
r: t.CUInt16T = 0
i: t.CInt = 0
while i < RDRAND_RETRY_LIMIT:
if rdrand16_step(c.Addr(r)) == 1:
return r
i += 1
return 0
def random_u32() -> t.CUInt32T:
r: t.CUInt32T = 0
i: t.CInt = 0
while i < RDRAND_RETRY_LIMIT:
if rdrand32_step(c.Addr(r)) == 1:
return r
i += 1
return 0
def random_u64() -> t.CUInt64T:
r: t.CUInt64T = 0
i: t.CInt = 0
while i < RDRAND_RETRY_LIMIT:
if rdrand64_step(c.Addr(r)) == 1:
return r
i += 1
return 0
def seed_u16() -> t.CUInt16T:
r: t.CUInt16T = 0
i: t.CInt = 0
while i < RDSEED_RETRY_LIMIT:
if rdseed16_step(c.Addr(r)) == 1:
return r
i += 1
return 0
def seed_u32() -> t.CUInt32T:
r: t.CUInt32T = 0
i: t.CInt = 0
while i < RDSEED_RETRY_LIMIT:
if rdseed32_step(c.Addr(r)) == 1:
return r
i += 1
return 0
def seed_u64() -> t.CUInt64T:
r: t.CUInt64T = 0
i: t.CInt = 0
while i < RDSEED_RETRY_LIMIT:
if rdseed64_step(c.Addr(r)) == 1:
return r
i += 1
return 0
# ============================================================
# Python random 标准库函数实现
# 默认类型t.CUInt64T (u64), t.CDouble (f64), t.CInt (i32)
# ============================================================
# ---------- 一、随机整数 ----------
def randint(a: t.CInt, b: t.CInt) -> t.CInt:
return t.CInt(a + t.CInt(random_u64() % t.CUInt64T(b - a + 1)))
def randrange(start: t.CInt, stop: t.CInt, step: t.CInt = 1) -> t.CInt:
width: t.CInt = 0
if step > 0:
width = (stop - start + step - 1) // step
else:
width = (start - stop - step - 1) // (-step)
return t.CInt(start + t.CInt(random_u64() % t.CUInt64T(width)) * step)
def getrandbits(k: t.CInt) -> t.CUInt64T:
r: t.CUInt64T = rdrand64()
if k >= 64:
return r
mask: t.CUInt64T = (t.CUInt64T(1) << k) - t.CUInt64T(1)
return r & mask
# ---------- 二、随机浮点数 ----------
def random() -> t.CDouble:
return t.CDouble(rdrand64() >> 11) * (t.CDouble(1.0) / t.CDouble(9007199254740992.0))
def uniform(a: t.CDouble, b: t.CDouble) -> t.CDouble:
return a + (b - a) * random()
def triangular(low: t.CDouble, high: t.CDouble, mode: t.CDouble) -> t.CDouble:
u: t.CDouble = random()
c: t.CDouble = (mode - low) / (high - low)
if u > c:
u = t.CDouble(1.0) - u
c = t.CDouble(1.0) - c
tmp: t.CDouble = low
low = high
high = tmp
return low + (high - low) * vipermath.sqrt(u * c)
def betavariate(alpha: t.CDouble, beta: t.CDouble) -> t.CDouble:
y: t.CDouble = gammavariate(alpha, t.CDouble(1.0))
if y != t.CDouble(0.0):
return y / (y + gammavariate(beta, t.CDouble(1.0)))
return t.CDouble(0.0)
def expovariate(lambd: t.CDouble) -> t.CDouble:
u: t.CDouble = random()
if u < t.CDouble(1e-300):
u = t.CDouble(1e-300)
return -vipermath.log(t.CDouble(1.0) - u) / lambd
def gammavariate(alpha: t.CDouble, beta: t.CDouble) -> t.CDouble:
u: t.CDouble = t.CDouble(0.0)
d: t.CDouble = t.CDouble(0.0)
c: t.CDouble = t.CDouble(0.0)
x: t.CDouble = t.CDouble(0.0)
v: t.CDouble = t.CDouble(0.0)
if alpha <= t.CDouble(0.0) or beta <= t.CDouble(0.0):
return t.CDouble(0.0)
if alpha < t.CDouble(1.0):
u = random()
if u < t.CDouble(1e-300):
u = t.CDouble(1e-300)
return gammavariate(alpha + t.CDouble(1.0), beta) * vipermath.pow(u, t.CDouble(1.0) / alpha)
d = alpha - t.CDouble(1.0) / t.CDouble(3.0)
c = t.CDouble(1.0) / vipermath.sqrt(t.CDouble(9.0) * d)
while 1:
x = gauss(t.CDouble(0.0), t.CDouble(1.0))
v = t.CDouble(1.0) + c * x
if v > t.CDouble(0.0):
v = v * v * v
u = random()
if u < t.CDouble(1.0) - t.CDouble(0.0331) * x * x * x * x:
return d * v * beta
if vipermath.log(u) < t.CDouble(0.5) * x * x + d * (t.CDouble(1.0) - v + vipermath.log(v)):
return d * v * beta
def gauss(mu: t.CDouble, sigma: t.CDouble) -> t.CDouble:
u1: t.CDouble = random()
u2: t.CDouble = random()
if u1 < t.CDouble(1e-300):
u1 = t.CDouble(1e-300)
z0: t.CDouble = vipermath.sqrt(t.CDouble(-2.0) * vipermath.log(u1)) * vipermath.cos(t.CDouble(2.0) * vipermath.U_M_PI * u2)
return mu + sigma * z0
def normalvariate(mu: t.CDouble, sigma: t.CDouble) -> t.CDouble:
NV_MAGICCONST: t.CDouble = t.CDouble(1.7155277699214135)
u1: t.CDouble = t.CDouble(0.0)
u2: t.CDouble = t.CDouble(0.0)
z: t.CDouble = t.CDouble(0.0)
zz: t.CDouble = t.CDouble(0.0)
while 1:
u1 = random()
u2 = random()
if u2 < t.CDouble(1e-300):
continue
z = NV_MAGICCONST * (u1 - t.CDouble(0.5)) / u2
zz = z * z / t.CDouble(4.0)
if zz <= t.CDouble(0.0) - vipermath.log(u2):
break
return mu + z * sigma
def lognormvariate(mu: t.CDouble, sigma: t.CDouble) -> t.CDouble:
return vipermath.exp(gauss(mu, sigma))
def vonmisesvariate(mu: t.CDouble, kappa: t.CDouble) -> t.CDouble:
if kappa <= t.CDouble(1e-6):
return vipermath.U_M_PI * t.CDouble(2.0) * random()
s: t.CDouble = t.CDouble(0.5) / kappa
r: t.CDouble = s + vipermath.sqrt(t.CDouble(1.0) + s * s)
u1: t.CDouble = t.CDouble(0.0)
u2: t.CDouble = t.CDouble(0.0)
u3: t.CDouble = t.CDouble(0.0)
z: t.CDouble = t.CDouble(0.0)
d: t.CDouble = t.CDouble(0.0)
q: t.CDouble = t.CDouble(0.0)
f: t.CDouble = t.CDouble(0.0)
theta: t.CDouble = t.CDouble(0.0)
two_pi: t.CDouble = vipermath.U_M_PI * t.CDouble(2.0)
while 1:
u1 = random()
z = vipermath.cos(vipermath.U_M_PI * u1)
d = t.CDouble(1.0) / (r + z)
u2 = random()
if u2 < t.CDouble(1.0) - d * d:
break
if u2 < (t.CDouble(1.0) - z) * vipermath.exp(kappa * (z - t.CDouble(1.0)) - d * kappa * r):
break
q = t.CDouble(1.0) / r
f = (q + z) / (t.CDouble(1.0) + q * z)
u3 = random()
if u3 > t.CDouble(0.5):
theta = mu + vipermath.acos(f)
else:
theta = mu - vipermath.acos(f)
while theta < t.CDouble(0.0):
theta += two_pi
while theta >= two_pi:
theta -= two_pi
return theta
def paretovariate(alpha: t.CDouble) -> t.CDouble:
u: t.CDouble = random()
if u < t.CDouble(1e-300):
u = t.CDouble(1e-300)
return t.CDouble(1.0) / vipermath.pow(t.CDouble(1.0) - u, t.CDouble(1.0) / alpha)
def weibullvariate(alpha: t.CDouble, beta: t.CDouble) -> t.CDouble:
u: t.CDouble = random()
if u < t.CDouble(1e-300):
u = t.CDouble(1e-300)
return alpha * vipermath.pow(t.CDouble(-1.0) * vipermath.log(t.CDouble(1.0) - u), t.CDouble(1.0) / beta)