1

我正在尝试将以下 C 函数转换为 Ruby,但无法弄清楚我做错了什么。我感觉它与数据类型有关,特别是在将它们传递给 Ruby 函数时,但无法查明确切的错误。

这是我的 C 代码:

#include <stdio.h>
#include <stdint.h>
uint32_t btle_calc_crc(uint32_t crc_init, uint8_t *data, int len) {
    uint32_t state = crc_init;
    uint32_t lfsr_mask = 0x5a6000; // 010110100110000000000000
    int i, j;
    for (i = 0; i < len; ++i) {
        uint8_t cur = data[i];
        for (j = 0; j < 8; ++j) {
            int next_bit = (state ^ cur) & 1;
            cur >>= 1;
            state >>= 1;
            if (next_bit) {
                state |= 1 << 23;
                state ^= lfsr_mask;
            }
        }
    }  
    return state;
}
int main(){
  uint32_t crc_init = 0x55555555;
  uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
    uint32_t crc = btle_calc_crc(crc_init, data, sizeof(data));
    printf("crc: %i\n", crc);
}

这是我的 Ruby 版本:

def calculate_crc(crc_init, data)
    lfsr_mask = 0x5a6000
    state = crc_init
    data.each do |byte|
        cur = byte
        (0..7).each do |i|
            next_bit = (state ^ cur) & 1;
            cur = (cur >> 1) && 0xff  # only 8 bit
            state = state >> 1
            if(next_bit == 1) 
                state = state | 1 << 23
                state = state ^ lfsr_mask
            end
        end
    end
    return(state)
end
crc = calculate_crc(0x555555, [0x01, 0x02, 0x03, 0x04, 0x05, 0x06])
puts "crc: #{crc}"
4

2 回答 2

3

看起来您正在为您的crc_init;使用不同的值 C 版本是0x55555555(8 个 5),Ruby 版本是0x555555(6 个 5)。你应该先纠正这个。

另外,我怀疑你需要使用&而不是&&在这条线上:

cur = (cur >> 1) && 0xff  # only 8 bit
于 2013-09-01T21:42:09.683 回答
2

在 Ruby 中计算 CRC 比这容易得多:

require 'zlib'
crc32 = Zlib.crc32('your message')

编辑:

或者,您可以使用“如何在 5 分钟内用 C 语言创建 Ruby 扩展”或“如何在 43 秒内用 C 语言创建 Ruby 扩展”来编写 Ruby 的 C 扩展。第一种方式更通用,并且可能会更快。

于 2013-09-01T21:34:32.790 回答