【发布时间】:2021-08-12 02:00:11
【问题描述】:
我正在尝试在 Dart 语言中实现一个用 masm32 编写的 32 位校验和宏。 这是我的理解:校验和函数将字符串作为输入,并以 4 字节整数返回校验和。 但我没有得到相同的结果。 请问有人看到我的错误吗?
; ecx : length of String variable
; esi : pointer to String variable
; eax : 'return' value of calculated checksum
CHECKSUM32_MACRO MACRO
LOCAL Checksum32Loop, Checksum32Done
xor eax,eax
cmp ecx,4
jb Checksum32Done
align 16
Checksum32Loop:
mov ebx,dword ptr [esi]
add eax,ebx
shl ebx,1
adc ebx,1
xor eax,ebx
add esi,4
sub ecx,4
jz Checksum32Done
cmp ecx,4
jae Checksum32Loop
mov edx,4
sub edx,ecx
sub esi,edx
mov ecx,4
jmp Checksum32Loop
Checksum32Done:
ENDM
int checksum(String src){
int i = src.length-1;
int res = 0;
do{
int c = src.codeUnitAt(i);
res += c;
String cBits = c.toRadixString(2);
int bitFort = int.parse(cBits[0]);
int transform = c << 1;
transform = transform + 1 + bitFort;
res = res ^ transform;
i--;
}while(i>=0);
return res;
}
我根据建议修改了代码,假设 ASCII 字符串总是 4 的倍数,是时候理解问题了。 但是还是不行。
String deComp = File(CHEMIN_FICHIER_DECOMP).readAsStringSync();
List<int> encoded = [];
for (int i =0; i<deComp.length; i++){
List<int> cUtf8 = utf8.encode(deComp[i]);
encoded.addAll(cUtf8);
}
print(checksum_stack(encoded));
_______
int checksum_stack(List<int> src){
int i = 0;
int res = 0;
do{
int c = fusion(src.sublist(i, i+4));
res += c;
String cBits = c.toRadixString(2).padLeft(8, '0');
int bitFort = int.parse(cBits[0]);
int transform = c << 1;
transform = transform + 1 +bitFort;
res = res ^ transform;
i+=4;
}while(i < src.length-4);
return res;
}
int fusion(List<int> str){
if (str.length != 4) {
throw "need multiple of 4!";
}
String hexStr = "";
str.forEach((c) {
hexStr += c.toRadixString(16).padLeft(2, '0');
});
return int.parse(hexStr,radix: 16);
}
【问题讨论】:
-
你的每个字符是 4 个字节吗?您输入的
esi是否直接指向字符? -
我不知道,抱歉在 C++ 中(调用者):
char * pData; pData =(char *)malloc(nFilesize); ReadFile(hInputFile, (void *)pData, nFilesize, $nBytesRead, 0); masmfunction((void*)pData, nFilesize)在 masm(接收者)中:masmfunction proc stdcall pSrc:DWORD, _Length:DWORD mov esi, pSrc mov ecx, _Length -
该代码确实看起来确实可以同时处理四个字节(
dword ptr [esi]和add esi,4)。 Dart 字符串不是字节序列,而是 16 位 UTF-16 代码单元。如果字符串仅为 ASCII,您可能会将每个字符视为一个字节,但如果不是,您可能需要先对字符串进行 UTF-8 编码,以获得与被散列的输入相媲美的东西。然后你需要处理这些字节。 -
我听从了您的建议,例如:
List<int> encoded = utf8.encode("aé");结果:[97, 195, 169] // a : 97, é : 195, 169所以,要达到每个字符 4 个字节,我必须用 0 完成?手动:[0, 0, 0, 97, 0, 0, 195, 169] -
您不需要达到每个字符四个字节,您需要一次处理四个 字节。无论它们来自哪里(例如,来自四个代码单元、三个代码单元或一个代码单元)。此外,您的代码似乎缺少对长度不是四倍数的字符串的处理。最好重写循环以使用 DWORD(4 个字节)。
标签: dart assembly masm checksum crc32