BigInteger.Parse()大量读取麻烦

时间:2018-04-08 15:45:19

标签: c# parsing biginteger

目前我正在尝试进行此挑战(http://cryptopals.com/sets/1/challenges/1),我在使用C#完成任务时遇到了一些麻烦。我似乎无法将数字解析成一个大整数。

所以代码如下所示:

        string output = "";
        BigInteger hexValue = BigInteger.Parse("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6");

        output = Convert.ToBase64String(hexValue.ToByteArray());
        Console.WriteLine(hexValue);
        Console.WriteLine(output);
        Console.ReadKey();
        return "";

目前我遇到的问题是当我运行程序时它失败并出现错误

  

System.FormatException:'无法解析该值。' 并且我不完全确定原因。

那么,从字符串中获取大整数到BigInt的适当方法是什么?

3 个答案:

答案 0 :(得分:7)

最初的问题

BigInteger.Parse方法期望值为十进制,而不是十六进制。您可以通过传入NumberStyles.HexNumber来“修复”。

使用BigInteger进行此

的更大问题

如果您只是尝试将十六进制数字字符串转换为字节,我将完全避免使用BigInteger。首先,如果原始字节数组以零开头,则可能会出现问题。零将不在结果字节数组中。 (示例输入:“0001” - 您希望获得两个字节,但在说服它解析十六进制后,您将只获得一个。)

即使您没有丢失任何信息,您从byte[]收到的BigInteger.ToByteArray()也不是您可能期望的。例如,请考虑此代码,该代码仅将数据转换为byte[]并通过BitConverter转换为十六进制:

BigInteger bigInt = BigInteger.Parse("1234567890ABCDEF", NumberStyles.HexNumber);
byte[] bytes = bigInt.ToByteArray();
Console.WriteLine(BitConverter.ToString(bytes));

输出是“EF-CD-AB-90-78-56-34-12” - 因为BigInteger.ToByteArray以小端顺序返回数据:

  

此方法返回的数组中的各个字节以little-endian顺序显示。也就是说,该值的低位字节位于高位字节之前。

这不是你想要的 - 因为它意味着原始字符串的 last 部分是字节数组的 first 部分等。

完全避免BigInteger

而是将数据直接解析为字节数组,如this questionthis one或其他各种数据。我不会在这里重现代码,但它很简单,具有不同的选项取决于您是否尝试创建简单的源代码或有效的程序。

有关转化的一般建议

一般来说,避免数据的中间表示是个好主意,除非你绝对相信你不会在这个过程中丢失信息 - 就像你在这里一样。在将结果转换为base64之前将十六进制字符串转换为字节数组是很好的,因为这不是有损转换。

所以你的转换是:

  • String(十六进制)到BigInteger:有损(在前导0的情况下是重要的,因为它们处于这种情况下)
  • BigIntegerbyte[]:没有损失
  • byte[]String(base64):not lossy

我建议:

  • String(十六进制)到byte[]:没有损失(假设你有一个偶数个nybbles要转换,这通常是一个合理的假设)
  • byte[]String(base64):not lossy

答案 1 :(得分:4)

使用NumberStyles.HexNumber

BigInteger.Parse("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6", 
                 NumberStyles.HexNumber,
                 CultureInfo.InvariantCulture);

如果您的号码应该始终为正数,请在字符串中添加前导零。

答案 2 :(得分:3)

问题是输入不是十进制而是十六进制,因此您需要传递一个额外的参数进行解析:

BigInteger number = BigInteger.Parse(
            hexString,
            NumberStyles.AllowHexSpecifier);