使用C#完成Cryptopals挑战1时遇BigInteger.Parse大数解析问题
解决C#中十六进制转Base64时的BigInteger解析问题
我来帮你搞定这个Cryptopals Set1第1题的问题,你的代码现在遇到两个核心问题,咱们一步步拆解解决:
首先,你的十六进制字符串有格式问题
你提供的十六进制字符串长度是奇数,BigInteger.Parse根本没法处理这种格式——因为每两个十六进制字符对应一个字节,奇数长度的字符串相当于少了半个字节,解析肯定失败。而且原挑战的正确十六进制字符串最后应该多一个d,完整内容是:
49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d
其次,用BigInteger处理字节序列是个错误思路
BigInteger是用来做数值计算的,不是处理原始字节流的工具。它的ToByteArray()方法会返回小端序的字节数组,还可能额外添加一个符号位字节(比如正数值会多一个0x00),这会直接导致Base64转换结果错误。
正确的解决方法
咱们换个思路,直接把十六进制字符串转换成字节数组,再转Base64,这才是符合挑战要求的做法。
方法1:手动实现十六进制转字节数组
写个简单的工具方法,逐字符处理转换:
public static byte[] HexToBytes(string hex) { if (hex.Length % 2 != 0) throw new ArgumentException("十六进制字符串长度必须是偶数"); byte[] result = new byte[hex.Length / 2]; for (int i = 0; i < hex.Length; i += 2) { result[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return result; }
方法2:用.NET内置工具(.NET 5及以上)
如果你的项目用的是较新的.NET版本,可以直接用System.Formats.Asn1里的内置方法,省得自己写:
using System.Formats.Asn1; byte[] bytes = AsnDecoder.DecodeHexString(hexString);
完整可运行代码
把这些整合起来,就能得到正确的Base64结果:
using System; class Program { static void Main() { // 修复后的十六进制字符串 string hexInput = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"; // 转字节数组 byte[] rawBytes = HexToBytes(hexInput); // 转Base64 string base64Output = Convert.ToBase64String(rawBytes); Console.WriteLine(base64Output); // 输出应该是:SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t } public static byte[] HexToBytes(string hex) { if (hex.Length % 2 != 0) throw new ArgumentException("十六进制字符串长度必须是偶数"); byte[] result = new byte[hex.Length / 2]; for (int i = 0; i < hex.Length; i += 2) { result[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return result; } }
总结一下你原代码的问题
- 奇数长度的十六进制字符串:导致
BigInteger.Parse无法解析,直接抛出错误; - 错误使用BigInteger处理字节流:它的字节数组输出不符合原始字节序列的要求,会破坏Base64转换的正确性。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

