Mysql Побитовые операции и фильтр - PullRequest
9 голосов
/ 03 октября 2011

Я пытаюсь реализовать побитовый фильтр, используя MYSQL (с udf, если необходимо).

Фильтр похож на AND, но я хочу использовать маску для создания новой битовой строки ... Позвольте мне объяснитьВы с примером:

Предположим, у меня есть таблица с BLOB-объектами, хранящими 8 битовых потоков:

  • data1: 10110110
  • data2: 01100010
  • data3: 00010011

Тогда у меня есть маска для применения, чтобы получить биты из данных, когда значение маски равно 1

  • MASK: 00101011

И так получим следующие ожидаемые результаты:

  • data1: 1010
  • data2: 1010
  • data3: 0011

Есть лиспособ оптимизации фильтрации без зацикливания на каждом бите «маски» для получения соответствующего значения в строке «данных» ...

УТОЧНЕНИЕ

I 'Мы только что взяли 8 битов за пост, но это больше похоже на 256 байтов

для Джо. Чтобы пояснить пример, маска 00101011 интерпретируется как: получить битзначение из поля данных в позиции 3,5,7,8, если вы читаете маску слева направо, нумерованное от бита 1 до бита 8 ... Надеюсь, это уточнение "ясно" ...

Ответы [ 2 ]

8 голосов
/ 04 октября 2011

Единственный способ, которым я знаю, делать то, что вы хотите, это что-то вроде

SELECT ((data >> 2) & 8) | ((data >> 1) & 4) | (data & 3) FROM ...

Очевидно, вам придется создавать выражение на основе вашей маски;это не очень сложно сделать, просто немного утомительно - вам нужно циклически перебирать биты в маске, что-то вроде этого:

var mask = 0b00101011;
var parts = new Array();
var shift = 0;
var unshift = 0;
while (mask > 0) {
    while ((mask & 1) == 0) {
        shift = shift + 1;
        mask = mask >> 1;
    }
    submask = 0;
    while ((mask & 1) == 1) {
        submask = submask + (1 << unshift);
        unshift = unshift + 1;
        mask = mask >> 1;
    }
    parts.push( "((data >> " + shift + ") & " + submask + ")" );
}
var expr = parts.join( " | " );
console.log(expr);

Приведенный выше пример кода на JavaScript, так что вы можете запустить его здесь как фрагмент и получить:

((data >> 0) & 3) | ((data >> 1) & 4) | ((data >> 2) & 8)

зарегистрировано на консоли, ноэто должно быть довольно легко портировать на другие языки.

8 голосов
/ 03 октября 2011

Вы можете использовать побитовые операторы в MySQL:

http://dev.mysql.com/doc/refman/5.0/en/bit-functions.html

Пример:

SELECT (data1 & b'00101011') as output1 FROM ......

Быстрый тест:

SELECT (b'10110110' & b'00101011') as output1

Это делает побитовое AND с двоичным шаблоном маски, которую вы указали.
Смотрите ссылку выше для получения дополнительной игрушки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...