Функция XOR для двух шестнадцатибайтовых массивов
Я пытаюсь выполнить исключающее ИЛИ двухбайтовых массивов и вернуть результат в виде шестнадцатеричной строки. Я преобразовал двухбайтовый массив в соответствующую двоичную строку. Каждый байт будет иметь биты, так как он имеет 8 байт.
byte[] key = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 };
byte[] PAN = { 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23 };
До сих пор я использовал метод, который преобразует массив байтов в соответствующее двоичное строковое значение, например "10101010101". Однако когда я выполняю приведенный ниже метод, чтобы получить XOR, я возвращаюсь со строкой связки смайликов, которые вероятно, это какой-то специальный символ ASCII.
Однако у меня нет никаких идей, как я могу это сделать. Я думал преобразовать двоичную строку в целое число, но это не очень хорошее решение, так как оно не будет соответствовать целому числу. У вас есть какие-нибудь идеи, пожалуйста? возможно, с каким-то образцом кода?public static string exclusiveOR(string string_1, string string_2)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < string_1.Length; i++)
sb.Append((char)(string_1[i] ^ string_2[(i % string_2.Length)]));
String result = sb.ToString();
return result;
}
4 ответа:
Вы делаете это правильно-ваш код
XOR
s символов двух строк, обернув вокруг второй, если первая из них окажется длиннее.Однако свойство XOR таково, что в выходных данных остаются только те биты, которые отличаются друг от друга. Следовательно, когда вы XOR
0x11
и0x12
, вы в конечном итоге получаете0x03
, который выглядит как сердце при отображении на консоли.
Попробуйте это:
public static string exclusiveOR(byte[] key, byte[] PAN) { if (key.Length == PAN.Length) { byte[] result = new byte[key.Length]; for (int i = 0; i < key.Length; i++) { result[i] = (byte)(key[i] ^ PAN[i]); } string hex = BitConverter.ToString(result).Replace("-", ""); return hex; } else { throw new ArgumentException(); } }
Как это работает: сначала вы проверяете, имеют ли массивы одинаковую длину, и если это так, вы выполняете операцию XOR над массивами. Метод
BitConverter.ToString()
преобразует массив байтов в строку, но поскольку существуют дефисы для разделения каждого шестнадцатеричного числа, вы можете использовать методReplace()
для удаления этих тире.
Я думаю, что
string
- это неправильный тип для этого. Вместо этого вы должны использоватьBitArray
, он даже уже имеет методXor()
.
ИМО было бы лучше разделить это на две части. Одна функция, чтобы сделать кусочно XOR и другая функция, чтобы преобразовать массив байтов в шестнадцатеричную строку.
public static byte[] exclusiveOR(byte[] arr1, byte[] arr2) { if (arr1.Length != arr2.Length) throw new ArgumentException("arr1 and arr2 are not the same length"); byte[] result = new byte[arr1.Length]; for (int i = 0; i < arr1.Length; ++i) result[i] = (byte) (arr1[i] ^ arr2[i]); return result; } public static string arrayToHexString(byte[] arr) { var sb = new StringBuilder(); for (int i = 0; i < arr.Length; ++i) sb.Append(arr[i].ToString("x2")); return sb.ToString(); }
Теперь вы можете просто сказать:
Console.WriteLine(arrayToHexString(exclusiveOR(arr1, arr2)));
Причина, по которой ваше решение печатает странные символы, заключается в том, что вы записываете значения ASCII
'1'
и'0'
, поскольку это символы в вашей строке. С'1'
это 0x31 и'0'
это 0x30, 0x30 0x31 результат операции XOR = 1. Затем вы вводите символ ASCII 0x01 (который является символом непечатаемый управляющий символ) в строку результата.