Mysql Bitwise操作和过滤

时间:2011-10-03 16:36:17

标签: mysql bit-manipulation

我尝试使用MYSQL(如果需要,使用udf)实现按位过滤器

过滤器类似于AND,但我想使用掩码来构建新的位串... 让我用一个示例解释你:

假设我有一个存储8位流的blob表:

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

然后我有一个掩码用于在掩码值为1

时从数据中获取位
  • MASK:00101011

因此得到以下预期结果:

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

有没有办法优化过滤,没有循环“掩码”的每一位,以获得“数据”行中的相应值...

澄清

我刚刚为帖子取了8位,但它更像是256字节

for Joe:为了澄清这个例子,掩码00101011被解释为:从位置3,5,7,8的数据字段获取位值,如果你从左到右读取掩码,从第1位枚举到第8位...希望这个澄清是“明确的”......

2 个答案:

答案 0 :(得分:8)

您可以在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,带有你指定的掩码的二进制模式 有关更多玩具,请参阅以上链接。

答案 1 :(得分:8)

我知道做你想做的事的唯一方法是

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)

登录到控制台,但移植到其他语言应该很容易。