C# 中字符的按位补码 vs C overflowexception
bitwise complement of a character in C# vs C overflowexception
我在 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]
的值是 '\u0005'
它抛出 OverflowException was Unhandled.
我不确定我应该做什么,感谢任何帮助。
当您翻转表示 char
的 32 位 int
的位时,它在 C 中始终有一个字节,最终会将高三个字节设置为 0xFF
.然而,C 在分配给 char
时愉快地砍掉高位字节,而 C# 的转换器抛出异常。
您可以通过使用强制转换代替转换来匹配 C 的功能来解决此问题:
snstring[i+1] -= '0';
snstring[i] = (char)(~snstring[i+1] & 0x07);
本质上,强制转换明确地告诉 C# 执行与 C 默认情况下相同的操作。
我做过类似的任务,即将一个数字作为输入并完全按照您的代码在 C# 中执行的操作执行。我将字符串作为输入并返回字符串。
下面是代码:
private string ComputeKey(string serialnumber)
{
if (string.IsNullOrEmpty(serialnumber))
{
throw new Exception("Cannot generate a key from a null or empty string");
}
serialnumber += '[=10=]';
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();
}
我在 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]
的值是 '\u0005'
它抛出 OverflowException was Unhandled.
我不确定我应该做什么,感谢任何帮助。
当您翻转表示 char
的 32 位 int
的位时,它在 C 中始终有一个字节,最终会将高三个字节设置为 0xFF
.然而,C 在分配给 char
时愉快地砍掉高位字节,而 C# 的转换器抛出异常。
您可以通过使用强制转换代替转换来匹配 C 的功能来解决此问题:
snstring[i+1] -= '0';
snstring[i] = (char)(~snstring[i+1] & 0x07);
本质上,强制转换明确地告诉 C# 执行与 C 默认情况下相同的操作。
我做过类似的任务,即将一个数字作为输入并完全按照您的代码在 C# 中执行的操作执行。我将字符串作为输入并返回字符串。 下面是代码:
private string ComputeKey(string serialnumber)
{
if (string.IsNullOrEmpty(serialnumber))
{
throw new Exception("Cannot generate a key from a null or empty string");
}
serialnumber += '[=10=]';
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();
}