我必须进行XOR来计算解密密钥。
我的预期关键是" 0123456789ABCDEFFEDCBA9876543210"我的样本输入是
(" 8D10DA193E98524379264ADFFD043632"和" C339F7EB7339FAC87FAF0478B500422")。第二个样本是(" 00000000000000000000000000000000"和" 0123456789ABCDEFFEDCBA9876543210")
因此,当我将我的第一个样本XOR得到这样的结果时就会出现这种情况" 7123456789ABCDEFFEDCBA9876543210"对于我的第二个样本,我得到的是#34; 123456789ABCDEFFEDCBA9876543210"领先的零正在被切断。
我尝试了各种各样的东西,但这里是我确定的代码:
static void Main(string[] args)
{
const string bdk1 = "8D10DA193E98524379264ADFFD043632";
const string bdk2 = "C339F7EB7339FAC87FAF0478B500422";
//const string bdk1 = "00000000000000000000000000000000";
//const string bdk2 = "0123456789ABCDEFFEDCBA9876543210";
const string expected = "0123456789ABCDEFFEDCBA9876543210";
BigInteger b1 = BigInteger.Parse(bdk1, NumberStyles.HexNumber);
BigInteger b2 = BigInteger.Parse(bdk2, NumberStyles.HexNumber);
BigInteger actual = b1 ^ b2;
string stringRet = actual.ToString("X");//.PadLeft(expected.Length, '0');
Console.WriteLine("Expected: " + expected);
Console.WriteLine("Actual : " + stringRet);
Console.ReadLine();
}
}
答案 0 :(得分:4)
我建议你解决问题,因为这是一个数据驱动的任务,所以使用以数据为中心的设计。所以从一个将字节数组表示为十六进制字符串的类开始。
class HexString
{
private byte[] _data;
}
您需要能够从字节数组和字符串构造它,因此为两者添加构造函数。我们的原始存储空间为byte[]
,因此第一个构造函数是微不足道的。第二个构造函数使用一些LINQ-fu来进行转换:
public class HexString
{
private byte[] _data;
public HexString(byte[] data)
{
_data = data;
}
public HexString(string data)
{
if ((data.Length & 1)!= 0) throw new ArgumentException("Hex string must have an even number of digits.");
_data = Enumerable.Range(0, data.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(data.Substring(x, 2), 16))
.ToArray();
}
}
如果您无法读取它,则无用,因此请覆盖ToString()
,以便您可以通过控制台输出它。在这个示例中,我使用了一个小技巧和BitConverter:
public override string ToString()
{
string hex = BitConverter.ToString(_data);
return hex.Replace("-","");
}
你需要能够对它进行异或,所以overload the XOR operator。请注意,有问题的值是字节流,而不是数字,因此我们将使用LINQ的Zip()方法一次一个地对每个字节进行异或运算以组合数组:
static public HexString operator ^(HexString LHS, HexString RHS)
{
return new HexString
(
LHS._data.Zip
(
RHS._data,
(a, b) => (byte)(a ^ b)
)
.ToArray()
);
}
完成所有这些后,您的主程序变得非常短(应该如此):
public class Program
{
static public void Main()
{
HexString bdk1 = new HexString("8D10DA193E98524379264ADFFD043632");
HexString bdk2 = new HexString("8C339F7EB7339FAC87FAF0478B500422");
const string expected = "0123456789ABCDEFFEDCBA9876543210";
HexString actual = bdk1 ^ bdk2;
Console.WriteLine("Expected: " + expected);
Console.WriteLine("Actual : " + actual);
Console.ReadLine();
}
输出:
Expected: 0123456789ABCDEFFEDCBA9876543210
Actual : 0123456789ABCDEFFEDCBA9876543210
请参阅DotNetFiddle上的完整解决方案。
答案 1 :(得分:1)
您正在将一个数字(BitInteger类型)转换为字符串。当然它不会有任何前导零。如果将其转换为字符串,也不会有任何其他数字。
如果由于某种原因确实需要一个前导零,唯一的方法是将转换结果的剩余字符串长度用“0”填充。
或者使用此ToString
重载:
number.ToString("X" + totalLengthYouNeed);
答案 2 :(得分:0)
这类似于组合Guids。您可以尝试将字符串转换为字节数组,然后将字节数组xor组合在一起。如果它有帮助,下面是Guids。稍加修改可能会让你到达目的地。
private Guid xorCombineGuids(Guid g1, Guid g2)
{
var g1Bytes = g1.ToByteArray();
var g2Bytes = g2.ToByteArray();
int length = g1.ToByteArray().Count();
byte[] xoredGuidBytes = new byte[length];
for (int i = 0; i < g1.ToByteArray().Count(); i++)
{
xoredGuidBytes[i] = (byte)(g1Bytes[i] ^ g2Bytes[i]);
}
return new Guid(xoredGuidBytes);
}