Реализованы сервисы ВМ2 - проверка сообщений и синхронизация с Б24 (деплой еще без перевода в боевой режим)
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
def _jcs(value: Any) -> str:
|
||||
"""Deterministic JSON close to RFC 8785 for this integer/string DTO domain."""
|
||||
if value is None:
|
||||
return "null"
|
||||
if value is True:
|
||||
return "true"
|
||||
if value is False:
|
||||
return "false"
|
||||
if isinstance(value, str):
|
||||
return json.dumps(value, ensure_ascii=False, separators=(",", ":"))
|
||||
if isinstance(value, int):
|
||||
return str(value)
|
||||
if isinstance(value, float):
|
||||
if not math.isfinite(value):
|
||||
raise ValueError("non-finite numbers are not JSON canonicalizable")
|
||||
raise TypeError("floating point values are forbidden in safety fingerprints")
|
||||
if isinstance(value, list):
|
||||
return "[" + ",".join(_jcs(item) for item in value) + "]"
|
||||
if isinstance(value, dict):
|
||||
keys = sorted(value, key=lambda key: key.encode("utf-16be"))
|
||||
return "{" + ",".join(f"{_jcs(key)}:{_jcs(value[key])}" for key in keys) + "}"
|
||||
raise TypeError(f"unsupported fingerprint type: {type(value).__name__}")
|
||||
|
||||
|
||||
def canonical_json(model: BaseModel | dict[str, Any]) -> bytes:
|
||||
value = model.model_dump(mode="json") if isinstance(model, BaseModel) else model
|
||||
return _jcs(value).encode("utf-8")
|
||||
|
||||
|
||||
def fingerprint(model: BaseModel | dict[str, Any]) -> bytes:
|
||||
return hashlib.sha256(canonical_json(model)).digest()
|
||||
Reference in New Issue
Block a user