module CRC::Calcurator
Attributes
bitmask[R]
bitsize[R]
initial_crc[R]
name[R]
polynomial[R]
reflect_input[R]
reflect_input?[R]
reflect_output[R]
reflect_output?[R]
xor_output[R]
Public Instance Methods
[](seq, *args)
click to toggle source
# File lib/crc.rb, line 55 def [](seq, *args) c = new(*args) c.update(seq) if seq c end
acrc(pre, post = nil, targetcrc = 0) → byte string as arc-code
click to toggle source
目的となる crc になるように、指定された crc に続くバイト列を逆算します。
出力されるバイト列は、crc のビット数を表現できるバイト数となります。
-
crc32(“123456789????”) の結果が 0 となるような、???? の部分を逆算する
seq = "123456789" arced_seq = CRC::CRC32.acrc(seq) p CRC::CRC32[seq + arced_seq] # => #<CRC::CRC32:00000000>
-
crc32(“123456789????ABCDEFG”) の結果が 0 となるような、???? の部分を逆算する
seq1 = "123456789" seq2 = "ABCDEFG" seq = seq1 + CRC::CRC32.acrc(seq1, seq2) + seq2 p CRC::CRC32[seq] # => #<CRC::CRC32:00000000>
-
crc32(“123456789????ABCDEFG”) の結果が 0x12345678 となるような、???? の部分を逆算する
seq1 = "123456789" seq2 = "ABCDEFG" targetcrc = 0x12345678 seq = seq1 + CRC::CRC32.acrc(seq1, seq2, targetcrc) + seq2 p CRC::CRC32[seq] # => #<CRC::CRC32:12345678>
# File lib/crc/acrc.rb, line 38 def acrc(pre, post = nil, targetcrc = 0) pre = pre.convert_internal_state_for(self) laststate = targetcrc.convert_target_state_for(self) state = unshiftbytes(post, laststate) bytesize = (bitsize + 7) / 8 pre <<= (bytesize * 8 - bitsize) unless reflect_input? bytes = pre.splitbytes("".b, bytesize, reflect_input?) state = unshiftbytes(bytes, state) state <<= (bytesize * 8 - bitsize) unless reflect_input? state.splitbytes("".b, bytesize, reflect_input?) end
combine(crc1, crc2) → new combined crc
click to toggle source
combine(crc1_int, crc2_int, crc2_len) → new combined crc
# File lib/crc.rb, line 96 def combine(*args) case args.size when 2 unless args[0].kind_of?(CRC) && args[1].kind_of?(CRC) raise ArgumentError, "When given two arguments, both arguments are should be CRC instance" end crc1 + crc2 when 3 Aux.combine(Integer(args[0].to_i), Integer(args[1].to_i), Integer(args[2].to_i), bitsize, polynomial, initial_crc, reflect_input?, reflect_output?, xor_output) else raise ArgumentError, "wrong number of arguments (given #{args.size}, expect 2..3)" end end
crc(seq, crc = nil)
click to toggle source
# File lib/crc.rb, line 75 def crc(seq, crc = nil) finish(update(seq, setup(crc))) end
digest(seq, crc = nil)
click to toggle source
# File lib/crc.rb, line 79 def digest(seq, crc = nil) Aux.digest(crc(seq, crc), bitsize) end
file(path, *args)
click to toggle source
# File lib/crc/_file.rb, line 11 def file(path, *args) new(*args).file(path) end
finish(state)
click to toggle source
# File lib/crc.rb, line 70 def finish(state) state = CRC.bitreflect(state, bitsize) if reflect_input? ^ reflect_output? state ^ xor_output & bitmask end
hexdigest(seq, crc = nil)
click to toggle source
# File lib/crc.rb, line 83 def hexdigest(seq, crc = nil) Aux.hexdigest(crc(seq, crc), bitsize) end
inspect()
click to toggle source
# File lib/crc.rb, line 144 def inspect "#{super}{#{to_str}}" end
magic()
click to toggle source
# File lib/crc/_magic.rb, line 70 def magic @magic = hexdigest(__cached_magic_code__).freeze singleton_class.class_eval { attr_reader :magic } @magic end
magicdigest(seq, crc = nil)
click to toggle source
# File lib/crc/_magic.rb, line 76 def magicdigest(seq, crc = nil) crc(seq, crc).to_magicdigest_for(self) end
magicnumber()
click to toggle source
# File lib/crc/_magic.rb, line 64 def magicnumber @magicnumber = crc(__cached_magic_code__) singleton_class.class_eval { attr_reader :magicnumber } @magicnumber end
pretty_inspect(q)
click to toggle source
# File lib/crc.rb, line 148 def pretty_inspect(q) q.text inspect end
setup(crc = nil)
click to toggle source
# File lib/crc.rb, line 61 def setup(crc = nil) crc ||= initial_crc crc ^= xor_output crc = CRC.bitreflect(crc, bitsize) if reflect_input? ^ reflect_output? crc & bitmask end
Also aliased as: init
Alias for: shiftbits_by_bitbybit
# File lib/crc/_shift.rb, line 11 def shiftbits_by_bitbybit(bitset, state) bitset = Array(bitset) if reflect_input? poly = CRC.bitreflect(polynomial, bitsize) bitset.each do |b| state ^= (1 & b) state = (state[0] == 0) ? (state >> 1) : ((state >> 1) ^ poly) end state else Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries| bitset.each do |b| s ^= (1 & b) << head s = (s[head] == 0) ? (s << 1) : (((carries & s) << 1) ^ poly) end s end end end
Also aliased as: shiftbits
Alias for: shiftbytes_by_bitbybit
standard input の場合は byte は上位ビットから、reflect input の場合は byte は下位ビットから計算されます。
# File lib/crc/_shift.rb, line 40 def shiftbytes_by_bitbybit(byteset, state) if reflect_input? poly = CRC.bitreflect(polynomial, bitsize) byteset.each_byte do |b| state ^= 0xff & b 8.times do state = (state[0] == 0) ? (state >> 1) : ((state >> 1) ^ poly) end end state else Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries| byteset.each_byte do |b| s ^= (0xff & b) << csh 8.times do s = (s[head] == 0) ? (s << 1) : (((carries & s) << 1) ^ poly) end end s end end end
Also aliased as: shiftbytes
to_magicdigest(crc)
click to toggle source
crc 値を与えると magicdigest へと変換したバイナリデータを返します。
crc には整数値、digest/hexdigest データ、変種を含む CRC
インスタンスを渡すことが出来ます。
# File lib/crc/_magic.rb, line 85 def to_magicdigest(crc) crc.to_magicdigest_for(self) end
to_str()
click to toggle source
# File lib/crc.rb, line 112 def to_str case when bitsize > 64 then width = 20 when bitsize > 32 then width = 16 when bitsize > 16 then width = 8 when bitsize > 8 then width = 4 else width = 2 end if reflect_input? ref = " reflect-in#{reflect_output? ? "/out" : ""}" else ref = reflect_output? ? " reflect-out" : "" end case initial_crc when 0 then init = "0" when bitmask then init = "~0" when 1 then init = "1" else init = "0x%0#{width}X" % initial_crc end case xor_output when 0 then xor = "0" when bitmask then xor = "~0" when 1 then xor = "1" else xor = "0x%0#{width}X" % xor_output end "CRC-%d-0x%0#{width}X%s init=%s xor=%s" % [bitsize, polynomial, ref, init, xor] end
unshift_table()
click to toggle source
# File lib/crc/_shift.rb, line 139 def unshift_table if reflect_input? if bitsize < 8 pad = 8 - bitsize shift = 0 else pad = 0 shift = bitsize - 8 end poly = ((CRC.bitreflect(polynomial, bitsize) << 1) | 1) << pad head = bitsize + pad @unshift_table = 256.times.map do |ch| state = ch << shift 8.times do |i| state <<= 1 state ^= poly unless state[head] == 0 end state >> pad end else raise NotImplementedError end singleton_class.module_eval { attr_reader :unshift_table } @unshift_table end
Alias for: unshiftbits_by_bitbybit
bitset を与えることで state となるような内部状態を逆算します。
# File lib/crc/_shift.rb, line 71 def unshiftbits_by_bitbybit(bitset, state) bitset = Array(bitset) if reflect_input? poly = (CRC.bitreflect(polynomial, bitsize) << 1) | 1 head = bitsize bitset.reverse_each do |b| state <<= 1 state ^= poly unless state[head] == 0 state ^= 1 & b end state else Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries| headbit = 1 << head lowoff = (head + 1) - bitsize poly = (poly >> 1) | headbit bitset.reverse_each do |b| tmp = s[lowoff] s >>= 1 s ^= poly unless tmp == 0 s ^= (1 & b) << head end s end end end
Also aliased as: unshiftbits
unshiftbytes_by_bitbybit(byteset, state)
click to toggle source
byteset を与えることで state となるような内部状態を逆算します。
# File lib/crc/_shift.rb, line 107 def unshiftbytes_by_bitbybit(byteset, state) if reflect_input? poly = (CRC.bitreflect(polynomial, bitsize) << 1) | 1 head = bitsize byteset.reverse_each_byte do |b| 7.downto(0) do |i| state <<= 1 state ^= poly unless state[head] == 0 state ^= b[i] end end state else Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries| headbit = 1 << head lowoff = (head + 1) - bitsize poly = (poly >> 1) | headbit byteset.reverse_each_byte do |b| 8.times do |i| tmp = s[lowoff] s >>= 1 s ^= poly unless tmp == 0 s ^= b[i] << head end end s end end end
unshiftbytes_by_table(byteset, state)
click to toggle source
# File lib/crc/_shift.rb, line 167 def unshiftbytes_by_table(byteset, state) if reflect_input? table = unshift_table if bitsize < 8 pad = 8 - bitsize shift = 0 mask = bitmask byteset.reverse_each_byte do |ch| state = (state << 8) ^ ch state = table[state >> bitsize] ^ (ch & mask) end else shift = bitsize - 8 mask = ~(~0 << shift) byteset.reverse_each_byte do |ch| state = table[state >> shift] ^ ((state & mask) << 8) state ^= ch end end state else unshiftbytes_by_bitbybit(byteset, state) end end
Also aliased as: unshiftbytes
variant?(obj)
click to toggle source
# File lib/crc.rb, line 87 def variant?(obj) obj.variant_for?(self) end