Сравните две шестнадцатеричные строки, чтобы найти количество совпадающих битов

У меня есть две шестнадцатеричные строки:

string x = "928fe46f228555621c7f42f3664530f9";
string y = "56cd8c4852cf24b1182300df2448743a";

Я пытаюсь преобразовать их в двоичные файлы, чтобы узнать, сколько битов совпадает между двумя шестнадцатеричными строками.

Я использовал эту функцию для преобразования HEX в двоичный:

 string GetBinaryStringFromHexString (string sHex)
 {
     string sReturn = "";
     for (int i = 0; i < sHex.length (); ++i)
     {
         switch (sHex [i])
         {
             case '0': sReturn.append ("0000"); break;
             case '1': sReturn.append ("0001"); break;
             case '2': sReturn.append ("0010"); break;
             case '3': sReturn.append ("0011"); break;
             case '4': sReturn.append ("0100"); break;
             case '5': sReturn.append ("0101"); break;
             case '6': sReturn.append ("0110"); break;
             case '7': sReturn.append ("0111"); break;
             case '8': sReturn.append ("1000"); break;
             case '9': sReturn.append ("1001"); break;
             case 'a': sReturn.append ("1010"); break;
             case 'b': sReturn.append ("1011"); break;
             case 'c': sReturn.append ("1100"); break;
             case 'd': sReturn.append ("1101"); break;
             case 'e': sReturn.append ("1110"); break;
             case 'f': sReturn.append ("1111"); break;
         }
     }
     return sReturn;
 }

Итак, строка x в двоичном формате равна --> 10010010100011111110010001101111001000101000010101010101011000100001110001111111011111101000010111100110110011010101001010011010011

и строка y в двоичном формате --> 01010110110011011000110001001000010100101100111100100100101100010001100000100011000000001000110000000011011111100100100010101001001010010010

Но теперь я застрял, как я могу выполнить операцию xor для двух строк, чтобы найти количество совпадающих битов? и как мне их посчитать?

Неважно, использую ли я Java или C++, кто-нибудь может помочь.

Спасибо,


person Pedro Xyze    schedule 09.10.2014    source источник
comment
Как только вы получите их в двоичном формате, просто используйте xor... если они равны, то это 0, иначе он даст 1 для разных битов...   -  person StackFlowed    schedule 09.10.2014
comment
@wrongAnswer Я не думаю, что вы вообще хотите XOR строк.   -  person Hunter McMillen    schedule 09.10.2014
comment
@HunterMcMillen, так что я начал с того, как только вы переведете их в двоичный файл ...   -  person StackFlowed    schedule 10.10.2014
comment
Возможный дубликат stackoverflow.com/questions/4259681/   -  person StackFlowed    schedule 10.10.2014
comment
упс, этот комментарий должен был быть @Pedro Xyze   -  person Hunter McMillen    schedule 10.10.2014
comment
Вам действительно нужна строка xor'd или просто количество совпадающих битов? Если вам просто нужен подсчет, все, что вам нужно сделать, это перебирать двоичные строки и сравнивать символы. xor-ing строки немного сложнее.   -  person azurefrog    schedule 10.10.2014
comment
Вы можете сначала попробовать сделать это с типом int, а затем попробовать то же самое с типом string.   -  person Jason    schedule 10.10.2014


Ответы (3)


В Java это довольно просто.

public static int numberOfMatchingOnes(String a, String b) {
    BigInteger aNumber = new BigInteger(a, 16);
    BigInteger bNumber = new BigInteger(b, 16);

    return aNumber.xor(bNumber).bitCount();
}

В С++ вы можете использовать набор битов. То, что вы ищете, называется вес Хэмминга.

Если вы действительно хотите сделать это без BigInteger: возьмите 4 символа из обеих строк, преобразуйте их в int, выполните операцию xor и подсчитайте однобитные числа. Повторяйте, пока струны не закончатся.

public static int numberOfMatchingOnes(String a, String b) {
    if (a.length() != b.length() || a.length() % 4 != 0) {
        throw new IllegalArgumentException("invalid strings");
    }

    int totalCount = 0;
    for (int i = (a.length()-1)/4; i >= 0; i--) {
        int aValue = Integer.valueOf(a.substring(i * 4, i * 4 + 4), 16);
        int bValue = Integer.valueOf(b.substring(i * 4, i * 4 + 4), 16);
        totalCount += Integer.bitCount(aValue ^ bValue);
    }
    return  totalCount;
}

Вы можете посмотреть Исходный код Java, чтобы увидеть, как работает bitCount().

person dusky    schedule 09.10.2014
comment
+1 для bitCount() - гораздо эффективнее моего решения. - person toddlermenot; 10.10.2014

У вас есть две строки. Почему бы не просмотреть их посимвольно и посмотреть, совпадают они или нет? Инициализируйте счетчик до нуля и начните увеличивать его для каждого совпадения и отображения в конце цикла. Гораздо проще.

Вот однострочное решение (с мощью всех библиотек в мире):

System.out.println(StringUtils.countMatches(new BigInteger("928fe46f228555621c7f42f3664530f9",16).xor(new BigInteger("56cd8c4852cf24b1182300df2448743a",16)).toString(2),"1"));
person toddlermenot    schedule 09.10.2014

Это зависит от вашей цели, если вы хотите найти, где они совпадают, вы можете использовать AND в C :

#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 & b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
} 

приведенный выше код справа налево сравнивает числа в двоичном формате и везде, где два бита были 1, затем возвращает 1, иначе возвращает 0

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

если вы хотите найти, где то же самое или не использовать XOR в C:

#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 ^ b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
} 
person Saeid    schedule 09.10.2014