PS: 從零寬字元隱寫的javascript程式碼提取出來的解密方式, 由於零寬字元隱寫的題目存在需要先判定存在哪些零寬字元, 勾選對應隱寫字元後再進行解密. 而據我調研, 各解密網站都不具備自動識別判斷解密的功能, 所以自寫了一個
# encoding=utf-8
import re
import math
from typing import Set, Union, Any
def get_use_chars(encode_str: str):
special_chars = ['\u200a', '\u200b', '\u200c', '\u200d', '\u200e', '\u200f', '\u202a', '\u202b', '\u202c',
'\u202d', '\u2062', '\u2063', '\ufeff']
pattern = "[" + "".join(re.escape(char) for char in special_chars) + "]"
found_chars = set(re.findall(pattern, encode_str))
return sorted(list(found_chars))
class UnicodeSteganographer:
def __init__(self):
self.chars = []
self.radix = 0
self.codelength_text = 0
def set_use_chars(self, new_chars: str):
if len(new_chars) >= 2:
self.chars = list(new_chars)
self.radix = len(self.chars)
self.codelength_text = math.ceil(math.log(65536, self.radix))
def decode_text(self, text: str) -> dict:
splitted = self.split_zerowidth_characters(text)
return {
'originalText': splitted['originalText'],
# splitted['hiddenText'],
'hiddenText': self.decode_from_zero_width_characters_text(splitted['hiddenText'])
}
def split_zerowidth_characters(self, str1: str) -> dict:
split_result = {
'originalText': re.sub('[' + ''.join(re.escape(char) for char in self.chars) + ']', '', str1),
'hiddenText': re.sub('[^' + ''.join(re.escape(char) for char in self.chars) + ']', '', str1)
}
return split_result
def decode_from_zero_width_characters_text(self, zero_width_str: str) -> str:
# 初始化
r = zero_width_str
decode_result = []
# 字元替換
for i in range(len(self.chars)): # 修改這裡為遍歷chars的長度
r = re.sub(self.chars[i], str(i), r)
# 解碼文字字元
for i in range(0, len(r), self.codelength_text):
char_code = int(r[i:i + self.codelength_text], self.radix)
decode_result.append(chr(char_code))
# 合併結果為字串並返回
return ''.join(decode_result)
if __name__ == '__main__':
# 只需要把零寬隱寫的文字貼上過來
zerotext = """
flag is not here!
"""
# 自動化計算方式
stegano = UnicodeSteganographer()
stegano.set_use_chars("".join(get_use_chars(zerotext)))
result = stegano.decode_text(zerotext)
print("try1:" + result['hiddenText'])
print("---------------------------------------------------------------------------")
# 預設計算方式
stegano2 = UnicodeSteganographer()
stegano2.set_use_chars('\u200c\u200d\u202c\ufeff')
result2 = stegano2.decode_text(zerotext)
print("try2:" + result2['hiddenText'])
原js解密指令碼參考
https://330k.github.io/misc_tools/unicode_steganography.js