50 lines
1.5 KiB
Python
50 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
|
|
|
|
XFALCON_PREFIX = "HUDR_sFnX+n5uAUNVsMPNK3DOP5wnti1Lc8Axjy5z88T61A=="
|
|
TEMP_VAR_XOR = bytes.fromhex("22eb4780")
|
|
TEMP_TE_TEMPLATE = bytes.fromhex(
|
|
"4b54cdabab77585a3a250077585a3a25000107020037df98acba"
|
|
"00000000"
|
|
"1eae285989015a563eda7b563efb00"
|
|
)
|
|
|
|
|
|
def xfalcon_te_raw_from_digest_hex(digest_hex: str) -> bytes:
|
|
digest_hex = digest_hex.strip().lower()
|
|
if len(digest_hex) != 64 or any(c not in "0123456789abcdef" for c in digest_hex):
|
|
raise ValueError("digest_hex must be 64 lowercase/uppercase hex chars")
|
|
|
|
temp = bytearray(TEMP_TE_TEMPLATE)
|
|
digest_ascii4 = digest_hex[:4].encode("ascii")
|
|
temp[26:30] = bytes(a ^ b for a, b in zip(digest_ascii4, TEMP_VAR_XOR))
|
|
checksum = (-(0x9F + sum(temp[2:44]))) & 0xFF
|
|
return bytes(b ^ checksum for b in temp)
|
|
|
|
|
|
def xfalcon_te_hex_from_digest_hex(digest_hex: str) -> str:
|
|
return xfalcon_te_raw_from_digest_hex(digest_hex).hex()
|
|
|
|
|
|
def xfalcon_value_from_digest_hex(digest_hex: str) -> str:
|
|
return f"{XFALCON_PREFIX}$TE_{xfalcon_te_hex_from_digest_hex(digest_hex)}"
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("digest_hex")
|
|
parser.add_argument("--value", action="store_true", help="print full __NS_xfalcon value")
|
|
args = parser.parse_args()
|
|
|
|
if args.value:
|
|
print(xfalcon_value_from_digest_hex(args.digest_hex))
|
|
else:
|
|
print(xfalcon_te_hex_from_digest_hex(args.digest_hex))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|