Files
Elydora-Python-SDK/elydora/utils.py
T
雷电芽衣 0f72a5e2f1 chore(python): audit core package
_client_common.py owns request building and EOR signing for both clients; types follow the Backend contract; the deprecated issue_token alias and token response aliases are removed; crypto, utils, and CLI comments trimmed.

Claude-Session: https://claude.ai/code/session_01Agoc9bRVE9KL7mmWtey9Vq
2026-09-02 23:05:37 -04:00

45 lines
1.3 KiB
Python

"""Utility helpers: UUIDv7, nonce generation, base64url encoding."""
from __future__ import annotations
import base64
import os
import struct
import time
def base64url_encode(data: bytes) -> str:
"""Encode bytes to base64url string with no padding."""
return base64.urlsafe_b64encode(data).rstrip(b"=").decode("ascii")
def base64url_decode(s: str) -> bytes:
"""Decode a base64url string (with or without padding) to bytes."""
s = s.replace("-", "+").replace("_", "/")
padding = 4 - len(s) % 4
if padding != 4:
s += "=" * padding
return base64.b64decode(s)
def generate_nonce() -> str:
"""Generate a 16-byte random nonce, base64url encoded."""
return base64url_encode(os.urandom(16))
def generate_uuidv7() -> str:
"""UUIDv7 (RFC 9562): 48-bit ms timestamp, version 7, variant 10, 74 random bits."""
timestamp_ms = int(time.time() * 1000)
ts_bytes = struct.pack(">Q", timestamp_ms)[2:]
rand_a = (struct.unpack(">H", os.urandom(2))[0] & 0x0FFF) | 0x7000
rand_b = bytearray(os.urandom(8))
rand_b[0] = (rand_b[0] & 0x3F) | 0x80
uuid_bytes = ts_bytes + struct.pack(">H", rand_a) + bytes(rand_b)
hex_str = uuid_bytes.hex()
return (
f"{hex_str[0:8]}-{hex_str[8:12]}-{hex_str[12:16]}-"
f"{hex_str[16:20]}-{hex_str[20:32]}"
)