VBA Access解密字符串存入变量时末尾莫名出现数字的问题排查
解密函数存入变量时末尾多出数字的问题排查
我在立即窗口手动执行解密代码时一切正常,但把解密结果存入字符串变量(比如strVar = decrypt(strEcnrypedCode))时,变量末尾会多出一个数字。请问可能的原因是什么?
相关代码如下:
Public Function Decrypt(DataIn As String) As String Dim CodeKey As String Dim arkdata1 As Long Dim strDataOut As String Dim intXOrValue1 As Integer Dim intXOrValue2 As Integer CodeKey = "12345678909" For arkdata1 = 1 To (Len(DataIn) / 2) intXOrValue1 = Val("&H" & (Mid$(DataIn, (2 * arkdata1) - 1, 2))) intXOrValue2 = Asc(Mid$(CodeKey, ((arkdata1 Mod Len(CodeKey)) + 1), 1)) strDataOut = strDataOut + Chr(intXOrValue1 Xor intXOrValue2) Next arkdata1 Decrypt = strDataOut End Function Public Function Encrypt(DataIn As String) As String Dim CodeKey As String Dim arkdata1 As Long Dim strDataOut As String Dim temp As Integer Dim tempstring As String Dim intXOrValue1 As Integer Dim intXOrValue2 As Integer CodeKey = "12345678909" For arkdata1 = 1 To Len(DataIn) intXOrValue1 = Asc(Mid$(DataIn, arkdata1, 1)) intXOrValue2 = Asc(Mid$(CodeKey, ((arkdata1 Mod Len(CodeKey)) + 1), 1)) temp = (intXOrValue1 Xor intXOrValue2) tempstring = Hex(temp) If Len(tempstring) = 1 Then tempstring = "0" & tempstring End If strDataOut = strDataOut + tempstring Next arkdata1 Encrypt = strDataOut End Function
问题原因
核心问题出在解密函数的循环终止条件上:
- 代码里用了
Len(DataIn) / 2作为循环上限,VBA中如果Len(DataIn)是奇数,这个除法会得到带小数的结果,而For循环会自动把小数向上取整成整数,导致循环多执行一次。 - 多出来的这次循环中,
Mid$(DataIn, (2 * arkdata1) - 1, 2)只能取到原字符串的最后一个字符(因为长度不够两位),Val("&H" & 单个字符)会把这个十六进制字符转成数值,再和密钥异或后转成字符,最终在结果末尾多出一个额外字符(表现为数字)。 - 立即窗口测试时可能刚好传入了偶数长度的加密字符串,所以没触发问题;但存入变量的场景中,可能传入了奇数长度的加密串,导致bug显现。
修复方案
把解密函数的循环条件改成整数除法,用\代替/,确保结果是整数:
For arkdata1 = 1 To (Len(DataIn) \ 2)
额外验证点
正常情况下,加密函数会把每个字符转成两位十六进制,所以加密结果长度应该是原字符串的2倍(必然是偶数)。如果出现奇数长度的加密串,要检查原字符串是否包含空字符或不可见字符,导致Len(DataIn)计算异常。
内容的提问来源于stack exchange,提问作者Mowaffak Bakkar
相关产品推荐
相关产品推荐

