如何解决如何使用任意值左移一个字符以生成 64 位整数?
我正在编写一个函数来计算字符串的 CRC *值。 ( * 8-64 的任意宽度)。 该函数接受 9 个参数,但为了说明左移的问题, 我只发布一个片段。
void leftshift(unsigned char* str,unsigned int n,int nshiftleft,unsigned __int64 *value)
{
unsigned __int64 x = str[0];
x = x << nshiftleft;
*value = x;
}
如果 str[0] 是 "A" (65) 并且 nshiftleft 是 56, 我期望值是 0x4100000000000000 (65
void leftshift(unsigned char* str,unsigned __int64 *value)
{
unsigned __int64 x = str[0];
x = x << 56;
*value = x;
}
如何实现?请帮忙。
编辑: 我是 Windows 用户,我打算使用脚本语言 AutoHotkey 中的此功能。
以下代码工作正常: 字符串“AutoHotkey”的 CRC-64/ECMA_182 值 = 0x36990A8E358262B4
void crc64(unsigned __int64 r,unsigned char* s,int n,unsigned __int64 *value)
{
unsigned __int64 poly = 0x42F0E1EBA9EA3693;
unsigned __int64 t = 0x8000000000000000;
unsigned __int64 x = 0;
for (int i=0; i<n; i+=1)
{
x = (__int64)s[i];
r ^= x << 56;
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
r = (r & t) ? ( (r << 1) ^ poly ) : (r << 1);
}
*value = r;
}
以上是完整代码。我用 LCC x64 (windows) 将它编译为 .obj(没有任何错误/警告) 并提取如下的 .text 部分:
5589e583ec1c535657c745f89336eaa9c745fcebe1f042c745f000000000c745f400000080c745e800000000c745ec00000000c745e400000000e92c0200008b45108b55e40fb6041089c0998945e88955ec8b45e88b55ec89c2b800000000c1e21831450831550c8b45088b550c2345f02355f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550c8b45088b550c2345f02355f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550c8b45088b550c2345f02355f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550c8b45088b550c2345f02355f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550c8b45088b550c2345f02355f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550c8b45088b550c2345f02355f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550c8b45088b550c2345f0235 5f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550c8b45088b550c2345f02355f483fa00750583f80074148b45088b550c0fa4c201d1e03345f83355fceb108b75088b7d0c89f089fa0fa4c201d1e089450889550cff45e48b45e43b45140f8cc8fdffff8b45188b4d088b5d0c89088958045f5e5b89ec5dc3
我能够使用 AutoHotkey 调用上述机器代码并获得正确的结果。 现在,我正在尝试使上述函数动态化,以便它可以处理 crc-8 到 crc-64 在一个函数中。
我在这里有一个用 AutoHotkey 编写的工作原型: https://www.autohotkey.com/boards/viewtopic.php?t=89364 (请向下滚动查看功能)
循环迭代对于解释性语言来说非常慢,因此求助于 c 机器代码。
感谢大家确认代码片段是正确的。 我将不得不检查 .obj 转储,但对 asm 一无所知。 我的结论是代码不能满足我的需要。
解决方法
当使用 Pelles C 编译时,以下在 x86 和 x64 中工作正常。 我将参数类型更改为 unsigned __int64 nshiftleft
void leftshift(unsigned char* str,unsigned int n,unsigned __int64 nshiftleft,unsigned __int64 *value)
{
unsigned __int64 x = str[0];
x = x << nshiftleft;
*value = x;
}
以上适用于 LCC-win x64,但不适用于 x86。
@r3mainer
我认为问题在于我提取的机器代码没有以下行。
x = x << nshiftleft;
0x0000000000000041 的值来自它前面的行。
如果我创建 Windows DLL,我相信链接器会解决这个问题。 但这不是一个选项,因为我必须为 x86 和 x64 分别创建两个 DLL。 使用机器码方法,我可以简单地在嵌入为 base64/hex 文本的函数中包含/调用它们。
谢谢大家。
,您不能通过移动 char
来创建 64 位整数。您需要创建一个 64 位数字并使用转换为 64 位的 char
对其进行初始化,然后您可以对其进行移位。不能移位大于字体大小的位数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。