BigInteger.Parse()大量读取麻烦

Joh*_*ohn 4 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 "";
Run Code Online (Sandbox Code Playgroud)

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

System.FormatException:'无法解析该值.' 而且我不完全确定为什么.

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

Jon*_*eet 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));
Run Code Online (Sandbox Code Playgroud)

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

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

这不是你想要的 - 因为它意味着原始字符串的最后一部分是字节数组的第一部分,等等.

BigInteger完全避免

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

关于转换的一般建议

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

所以你的转换是:

  • String(hex)to BigInteger:有损(在前导0的情况下是重要的,因为它们处于这种情况)
  • BigIntegerto byte[]:没有损失
  • byte[]String(base64):没有损失

我推荐:

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


nvo*_*igt 5

使用NumberStyles.HexNumber

BigInteger.Parse("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6", 
                 NumberStyles.HexNumber,
                 CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)

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