将C++函数转换为C#
Convert C++ function to C#
我正在尝试将以下C++函数移植到C#:
QString Engine::FDigest(const QString & input)
{
if(input.size() != 32) return "";
int idx[] = {0xe, 0x3, 0x6, 0x8, 0x2},
mul[] = {2, 2, 5, 4, 3},
add[] = {0x0, 0xd, 0x10, 0xb, 0x5},
a, m, i, t, v;
QString b;
char tmp[2] = { 0, 0 };
for(int j = 0; j <= 4; j++)
{
a = add[j];
m = mul[j];
i = idx[j];
tmp[0] = input[i].toAscii();
t = a + (int)(strtol(tmp, NULL, 16));
v = (int)(strtol(input.mid(t, 2).toLocal8Bit(), NULL, 16));
snprintf(tmp, 2, "%x", (v * m) % 0x10);
b += tmp;
}
return b;
}
其中一些代码很容易移植,但我在这部分遇到了问题:
tmp[0] = input[i].toAscii();
t = a + (int)(strtol(tmp, NULL, 16));
v = (int)(strtol(input.mid(t, 2).toLocal8Bit(), NULL, 16));
snprintf(tmp, 2, "%x", (v * m) % 0x10);
我发现(int)strtol(tmp, NULL, 16)
等于C#中的int.Parse(tmp, "x")
,snprintf
是String.Format
,但我不确定其余部分
如何将这个片段移植到C#?
编辑我怀疑您的代码实际上对输入数据进行了MD5摘要。请参阅以下基于该假设的片段。
翻译步骤
一些提示应该工作良好1
Q:
tmp[0] = input[i].toAscii();
bytes[] ascii = ASCIIEncoding.GetBytes(input);
tmp[0] = ascii[i];
Q:
t = a + (int)(strtol(tmp, NULL, 16));
t = a + int.Parse(string.Format("{0}{1}", tmp[0], tmp[1]),
System.Globalization.NumberStyles.HexNumber);
Q:
v = (int)(strtol(input.mid(t, 2).toLocal8Bit(), NULL, 16));
没有关于toLocal8bit的线索,需要阅读Qt文档。。。
Q:
snprintf(tmp, 2, "%x", (v * m) % 0x10);
{
string tmptext = ((v*m % 16)).ToString("X2");
tmp[0] = tmptext[0];
tmp[1] = tmptext[1];
}
如果。。。它只是MD5
你可以直接尝试一下,看看它是否达到了你需要的效果:
using System;
public string FDigest(string input)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] ascii = System.Text.Encoding.ASCII.GetBytes (input);
byte[] hash = md5.ComputeHash (ascii);
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
sb.Append (hash[i].ToString ("X2")); // "x2" for lowercase
return sb.ToString();
}
1明确未优化,旨在作为快速提示;根据需要优化
更多提示:
t是一个两字节的缓冲区,并且只写入第一个字节,留下一个尾随的nul。因此,t总是一个恰好由一个字符组成的字符串,并且一次处理一个十六进制数字的字符。所以我认为
tmp[0] = input[i].toAscii();
t = a + (int)(strtol(tmp, NULL, 16));
这大致是int t = a + Convert.ToInt32(input.substring(i, 1), 16);
——从输入中取一位数字,并将其十六进制值添加到您从表中查找的值中。(我假设toAscii只是将已经是十六进制数字的QString字符映射到strtol的ASCII中,所以如果你已经有一个十六进制数字字符串,这是可以的。(
下一个
v = (int)(strtol(input.mid(t, 2).toLocal8Bit(), NULL, 16));
这意味着从偏移量t的输入中查找两个字符,即input.substring(t, 2)
,然后再次将它们转换为十六进制整数。v = Convert.ToInt32(input.substring(t, 2), 16);
现在,碰巧的是,我认为你实际上只会在这里使用第二个数字,因为计算是(v * a) % 0x10
,但是嘿。如果我们再次使用十六进制数字的QString,那么toLocal8应该与toAscii是相同的转换——我不清楚为什么您的代码在这里有两个不同的函数。
最后将这些值转换为tmp中的一个数字,然后将其附加到b
snprintf(tmp, 2, "%x", (v * m) % 0x10);
b += tmp;
(2是缓冲区的长度,由于我们需要一个尾随的nul,所以只写了1(即
int digit = (v * m) % 0x10;
b += digit.ToString("x");
应该这样做。我个人会把mod 16写成一个逻辑和& 0xf
,因为它的目的是把值降到一个数字。
还要注意,在您的代码中,i
从未被设置过——我想这是一个循环还是您为了简洁而省略的东西?
总之,
int t = a + Convert.ToInt32(input.substring(i, 1), 16);
int v = Convert.ToInt32(input.substring(t, 2), 16);
int nextDigit = (v * m) & 0xf;
b += nextDigit.ToString("x");
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C++:用户定义的显式类型转换函数错误
- 为什么下面带有非常量转换函数的代码没有歧义?
- 为什么转换函数声明不需要至少一个定义类型说明符
- PCL:当我在setConditionFunction中使用std::bind 时,没有合适的转换函数
- C++ 通过自定义赋值运算符隐式转换函数参数
- 当我使用 void 函数的返回值(通过强制转换函数指针)时,究竟会发生什么?
- 在C++中自动向下转换函数参数
- static_cast:转换函数模板——它们真的有效吗
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类
- 隐式转换函数的返回对象时是否会影响性能?
- C++不存在合适的转换函数
- 为什么允许 int 和 const int 使用不同的转换函数?
- 使用转换函数直接初始化
- 为什么用户定义的转换函数模板不能有推导的返回类型?
- 为什么我会收到转换函数错误
- 选择用于赋值初始化的转换函数的优先级
- 我收到错误:没有合适的转换函数从 std::basic_istream<char、std::char_traits<char>> 到 char 存在
- 具有转换函数的 lambda,指向具有 C++ 链接的函数的指针
- 使用模板和部分专用化生成类型转换函数