在Ruby中计算字节的奇偶校验

在Ruby中计算字节的奇偶校验,ruby,des,3des,parity,Ruby,Des,3des,Parity,在Ruby中,计算字节是否具有奇偶校验的最佳方法是什么?我有一个版本正在运行: result = "AB".to_i(16).to_s(2).count('1').odd? => true 不过,将数字转换为字符串并计算“1”似乎是一种糟糕的奇偶校验计算方法。有更好的方法吗 我希望能够计算3DES密钥的奇偶校验。最后,我想将偶数字节转换为奇数字节 谢谢, Dan可能一个包含255个条目的数组的查找表是“Ruby”中最快的解决方案 在C语言中,我会伪装和变换。或者,如果我有SSE4,我会将

在Ruby中,计算字节是否具有奇偶校验的最佳方法是什么?我有一个版本正在运行:

result = "AB".to_i(16).to_s(2).count('1').odd?
=> true
不过,将数字转换为字符串并计算“1”似乎是一种糟糕的奇偶校验计算方法。有更好的方法吗

我希望能够计算3DES密钥的奇偶校验。最后,我想将偶数字节转换为奇数字节

谢谢,
Dan

可能一个包含255个条目的数组的查找表是“Ruby”中最快的解决方案

在C语言中,我会伪装和变换。或者,如果我有SSE4,我会将POPCNT指令与内联汇编程序一起使用。如果需要高性能,请使用C编写一个本机扩展,它可以执行上述任一操作


你看了这张照片了吗?这样就不需要编写自己的实现了

要计算奇偶校验,您可以使用以下内容:

require 'rubygems'
require 'inline'  # RubyInline (install with `gem install RubyInline`)

class Fixnum
  # native ruby version: simpler but slow
  # algorithm from: 
  #   http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel      
  def parity_native
    (((self * 0x0101010101010101) & 0x8040201008040201) % 0x1FF) & 1
  end

  class << self
    # inline c version using RubyInline to create c extension
    # 4-5 times faster than native version
    # use as class method: 
    #   Fixnum.parity(0xAB)
    inline :C do |builder|
      builder.c <<-EOC
      int parity_c(int num) {  
        return (
            ((num * 0x0101010101010101ULL) & 0x8040201008040201ULL) % 0x1FF
          ) & 1;
      }
      EOC
    end
  end

  def parity
    self.class.parity_c(self)
  end

  def parity_odd?
    1 == parity
  end
  def parity_even?
    0 == parity
  end
end

0xAB.parity        # => 1 
0xAB.parity_odd?   # => true 
0xAB.parity_even?  # => false
(0xAB + 1).parity  # => 0
可以缩短为

x = 'AB'.to_i(16)
p = x & 1
p += x & 1 until (x >>= 1) == 0

如果你想要看不懂的东西☺

除非你拥有的不够快,否则就保留它。它清晰简洁,性能比你想象的要好

我们将根据数组查找(我测试过的最快方法)对所有内容进行基准测试:

ODD_PARITY = [
  false,
  true,
  true,
  ...
  true,
  false,
]

def odd_parity?(hex_string)
  ODD_PARITY[hex_string.to_i(16)]
end
  • 数组查找以每秒640000字节的速率计算奇偶校验
  • Bowsersenior的C代码以每秒640000字节的速度计算奇偶校验
  • 您的代码以每秒284000字节的速率计算奇偶校验
  • Bowsersenior的本机代码以每秒171000字节的速率计算奇偶校验
  • 西奥的缩短代码以每秒128000字节的速度计算奇偶校验

将原始解决方案与备忘录一起使用如何?这将仅为每个整数值计算一次

class Fixnum
  # Using a class variable for simplicity, and because subclasses of
  # Fixnum—while very uncommon—would likely want to share it. 
  @@parity = ::Hash.new{ |h,i| h[i] = i.to_s(2).count('1').odd? }
  def odd_parity?
    @@parity[self]
  end
  def even_parity?
    !@@parity[self]
  end
end

"AB".to_i(16).odd_parity?
#=> true

我将构造一个包含16个条目的表(作为一个16个字符的表),对应于一个字节的每个半字节。条目为0,1,1,2,1,2,….4

要测试您的字节

遮住左半字节并进行查找,记住数字。 做向右移动4,然后进行第二次查找,将结果编号与前一个编号相加以提供总和

然后从总和中测试低阶位。如果是1,则字节为奇数;如果是0,则字节为偶数。如果结果为偶数,则使用xor指令翻转高阶位。 这种查找方法比单次移位将字节中的位相加要快得多

给我发电子邮件,要一个简单的函数来实现8字节的奇偶校验。3DES使用3组8字节

ODD_PARITY = [
  false,
  true,
  true,
  ...
  true,
  false,
]

def odd_parity?(hex_string)
  ODD_PARITY[hex_string.to_i(16)]
end
class Fixnum
  # Using a class variable for simplicity, and because subclasses of
  # Fixnum—while very uncommon—would likely want to share it. 
  @@parity = ::Hash.new{ |h,i| h[i] = i.to_s(2).count('1').odd? }
  def odd_parity?
    @@parity[self]
  end
  def even_parity?
    !@@parity[self]
  end
end

"AB".to_i(16).odd_parity?
#=> true