# -*- coding: utf-8 -*- """암호 DBF(BDQTY.DBF) 자리별 변환 — 복호(bdqty._dec)의 역변환으로 다시 숨김. 근거: STC_난독화_상태.md · 29_암호화자료의_뼈대.md · bdqty.py(자리별 표 PARAMS) A 암호 = rol(평문, r) + k B 암호 = rol(평문 + k, r) X 암호 = rol(평문, r) ^ k 표에 없는 자리(글자 칸 등)는 풀 수도 숨길 수도 없음 — 그 자리를 건드리는 쓰기는 오류. """ from __future__ import annotations from bdqty import PARAMS, _dec def _rol(v: int, r: int) -> int: return ((v << r) | (v >> (8 - r))) & 0xFF if r else v def enc_byte(p: int, param: tuple[str, int, int]) -> int: kind, r, k = param if kind == "A": return (_rol(p, r) + k) & 0xFF if kind == "B": return _rol((p + k) & 0xFF, r) return _rol(p, r) ^ k def covers(off: int, n: int) -> bool: return all(j in PARAMS for j in range(off, off + n)) class BdqtyCodec: """DbfTable codec — off = 레코드 안 칸 시작 자리.""" def decode(self, cipher: bytes, off: int) -> bytes: if not covers(off, len(cipher)): raise ValueError(f"BDQTY 자리 {off}~{off + len(cipher) - 1} 은 복호 표에 없음") return bytes(_dec(c, PARAMS[off + i]) for i, c in enumerate(cipher)) def encode(self, plain: bytes, off: int) -> bytes: if not covers(off, len(plain)): raise ValueError(f"BDQTY 자리 {off}~{off + len(plain) - 1} 은 암호 표에 없음") return bytes(enc_byte(p, PARAMS[off + i]) for i, p in enumerate(plain))