異体字セレクターを使ったステガノグラフィのTypeScript化
Unicodeの異体字セレクターを使ったステガノグラフィ:秘密の文字列をテキストにこっそり隠し込む方法 #JavaScript - Qiitaを実際に試してみたかったが、どうせならTypeScriptで実装して、ちゃんと動かしたい。
というわけで実装した。
class Steganography {
static #components = { VS_BEGIN: 0xfe00, STR_EMPTY: "", REPLACER: /\uFEFF[\uFE00-\uFE0F]+/u, toHex(value: number) { return value.toString(16); }, toHexDecimal(str: string): number { return Number.parseInt(str, 16); }, encode: { PREFIX: "\u{FEFF}" } }
static encode(body: string, hidden: string): string { const { VS_BEGIN, STR_EMPTY, encode, toHex, toHexDecimal } = this.#components; return encode.PREFIX + [...hidden].flatMap(c => [...toHex(c.charCodeAt(0))]) .map((s) => String.fromCodePoint(VS_BEGIN + toHexDecimal(s))) .join(STR_EMPTY) + body }
static decode(value: string): [body: string, hidden: string] { const { VS_BEGIN, STR_EMPTY, REPLACER, toHex, toHexDecimal } = this.#components;
let hidden = STR_EMPTY; const body = value.replace(REPLACER, ([_, ...variationSelectors]) => { hidden += variationSelectors .map((c) => toHex(c.codePointAt(0)! - VS_BEGIN)) .reduce<string[][]>((acc, _, index, arr) => { return index % 2 === 0 ? [...acc, arr.slice(index, index + 2)] : acc; }, []) .map(([a, b]) => String.fromCharCode(toHexDecimal(a + b))) .join(STR_EMPTY); return STR_EMPTY; }); return [body, hidden] }}