2011-10-03 51 views
9

我尝试(如果需要使用UDF)实现使用MYSQL按位滤波器Mysql的位运算和滤波

过滤器是一样的东西和,但我想用面膜来建立一个新的比特串... 让我用一个样本说明你:

假设我有一个表BLOB存储8个比特流:

  • 数据1:10110110
  • 数据2:01100010
  • 数据3:00010011

然后我就口罩适用于得到的数据位时,掩码值为1

  • MASK:00101011

因此得到以下预期结果:

  • 数据1:1010
  • DAT A2:1010
  • 数据3:0011

有没有办法来优化过滤,没有循环的“面具”的每一点,以获得在“数据”行的相应值...

澄清

我刚8位的职位,但它更像是256个字节

乔:为了澄清为例,面具00101011被解释为:得到位VAL如果你从左至右读取掩码,从第1位到第8位列举...希望这个解释是“清除”...

+0

我没有看到这面具和这些行应该如何返回数据 – Joe

+0

在我看来,这真的很难实现这一点没有一个循环。 – Karolis

回答

7

你可以从数据字段在位置3,5,7,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

我不认为这是他想要的。 – Karolis

7

我知道这样做的唯一方式,你想要的东西是一样的东西

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) 

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