1

我在 C 中有以下代码,它将根据输入的序列号生成密钥。

unsigned int32 passkey(unsigned int32 snumber)
{
    char snstring[11];
    unsigned int32 pwd;
    int i = 0;
    itoa(snumber,10,snstring);
    do{
        snstring[i+1] -= '0';
        snstring[i] = ~snstring[i+1];
        snstring[i] &= 0x07;
        i++;
    }while(i < 9);
    snstring[9] <<= 1;
    snstring[9] &= 0x07;
    pwd = atoi32(snstring);
    return (pwd);
}

我需要将其转换为 C# 代码,我尝试过以下操作:

private uint ComputeKey(uint snumber)
        {
            char[] snstring = new char[11];
            UInt32 pwd;
            int i = 0;
            snstring = snumber.ToString().ToCharArray();

            do
            {
                snstring[i + 1] = Convert.ToChar(snstring[i + 1] - '0');
                snstring[i] = Convert.ToChar(~Convert.ToInt32(snstring[i + 1]));
                snstring[i] &= Convert.ToChar(Convert.ToInt32(0x07));
                i++;
            } while (i < 9);
            snstring[9] <<= 1;
            snstring[9] &= Convert.ToChar(0x07);
            pwd = Convert.ToUInt32(snstring);
            return (pwd);
        }

snstring[i] = Convert.ToChar(~Convert.ToInt32(snstring[i + 1]));程序在这一行抛出异常。

另一个值得注意的行为是,例如我输入为

151972634

然后,在这一行snstring[i] = Convert.ToChar(~Convert.ToInt32(snstring[i + 1]));的值为snstring[i+1]is'\u0005' 并且它抛出 OverflowException was Unhandled。

我不确定我应该做什么,任何帮助表示赞赏。

4

2 回答 2

1

int当您翻转表示 a的 32 位的位时char,它在 C 中始终有一个字节,最终将高三个字节设置为0xFF。但是,C 很高兴在分配给 时切断了高字节char,而 C# 的转换器抛出异常。

您可以通过使用强制转换代替转换来匹配 C 的功能来解决此问题:

snstring[i+1] -= '0';
snstring[i] = (char)(~snstring[i+1] & 0x07);

本质上,强制转换显式地告诉 C# 做与 C 默认做的事情相同的事情。

于 2016-08-16T14:08:24.247 回答
1

我已经完成了类似的任务,即将一个数字作为输入并完全按照您的代码在 C# 中所做的工作。我将字符串作为输入并返回字符串。下面是代码:

private string ComputeKey(string serialnumber)
        {
            if (string.IsNullOrEmpty(serialnumber))
            {
                throw new Exception("Cannot generate a key from a null or empty string");
            }

            serialnumber += '\0';
            var length = serialnumber.Length;
            byte[] snbytes = Encoding.UTF8.GetBytes(serialnumber);
            for (int i = 0; i < length - 1; i++)
            {
                snbytes[i + 1] -= 0x30;
                snbytes[i] = (byte)~snbytes[i + 1];
                snbytes[i] &= 0x07;
            }
            snbytes[length - 1] <<= 1;
            snbytes[length - 1] &= 0x07;

            var sb = new StringBuilder();
            for (int j = 0; j < length - 1; j++)
            {
                sb.Append(snbytes[j].ToString());
            }

            return sb.ToString();
        }
于 2016-08-17T17:04:16.533 回答