SQL Server中varbinary转varchar:从0x7E959C9ABB818C还原'1081X'
从你给出的测试结果一眼就能看出来:常规的ASCII/UTF-8/UTF-16编码转换根本没法把0x7E959C9ABB818C转成'1081X'——毕竟CONVERT(VARBINARY(28), '1081X')得到的是标准的ASCII编码0x3130383158,和目标二进制完全对不上。这说明这个varbinary(28)字段的内容不是直接存储字符编码,而是经过了某种自定义转换(比如加密、特殊编码规则,甚至是带校验位的处理)。
下面是你可以按优先级尝试的解决步骤:
1. 先找应用层的存储逻辑(最省心的方法)
直接去看写入这个字段的应用程序代码,搞清楚它是怎么把'1081X'变成0x7E959C9ABB818C的。比如:
- 是不是用了简单的异或加密(每个字节和固定密钥做异或运算)?
- 有没有自定义的字符映射表或者编码规则?
- 会不会是用了DES、AES这类对称加密算法?
找到正向转换的逻辑后,直接反向实现就能轻松还原明文——不管是在SQL里写函数还是在应用里处理都能搞定。
2. 尝试逆向分析已知的明文-二进制对(适合找不到代码的情况)
你现在有一组明确的对应关系:'1081X' ↔ 0x7E959C9ABB818C,可以拆解字节来碰规律:
- 明文
'1081X'的ASCII字节是:0x31, 0x30, 0x38, 0x31, 0x58(共5字节) - 目标二进制是7字节:
0x7E, 0x95, 0x9C, 0x9A, 0xBB, 0x81, 0x8C
先试试常见的字节运算,比如异或:
-- 测试前5个二进制字节和明文字节的异或结果 SELECT CHAR(0x7E ^ 0x31) AS Byte1_XOR, -- 返回 'O' CHAR(0x95 ^ 0x30) AS Byte2_XOR, -- 不可见控制字符 CHAR(0x9C ^ 0x38) AS Byte3_XOR, -- 不可见控制字符 CHAR(0x9A ^ 0x31) AS Byte4_XOR, -- 不可见控制字符 CHAR(0xBB ^ 0x58) AS Byte5_XOR; -- 不可见控制字符
从结果看,只有第一个字节是可见字符,说明大概率不是简单异或。剩下的两个字节(0x81, 0x8C)可能是校验位、固定前缀/后缀,或者是编码时额外添加的信息。
如果只有这一组对应关系,逆向分析的难度会很高——建议尽量收集更多的明文和对应的二进制值,这样更容易找到规律。
3. 排除其他常见可能性
- 试试用不同的编码页转换,确认是不是罕见编码:
SELECT CONVERT(VARCHAR(28), 0x7E959C9ABB818C) COLLATE Chinese_PRC_CI_AS AS GB2312_Test, CONVERT(VARCHAR(28), 0x7E959C9ABB818C) COLLATE Japanese_Unicode_CI_AS AS ShiftJIS_Test;
但大概率会返回乱码,因为目标二进制的字节范围不符合常见多字节编码的规则。
- 检查是不是压缩数据:用SQL Server的
COMPRESS函数试试对比结果:
SELECT COMPRESS('1081X'); -- 返回 0x1F8B0800000000000400734BCB4B57001001D0604000000
显然和0x7E959C9ABB818C不匹配,直接排除压缩的可能。
最后总结
最靠谱的解决方案还是找到应用程序中处理这个字段的代码逻辑——毕竟这不是标准的字符存储格式。如果实在找不到代码,就尽量多收集几组明文和对应的二进制值,这样逆向分析的成功率会高很多。
内容的提问来源于stack exchange,提问作者pgee70

