Module: CRC::ModuleClass

Defined in:
lib/crc.rb,
lib/crc/acrc.rb,
lib/crc/_byruby.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#bitmaskObject (readonly)

Returns the value of attribute bitmask.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def bitmask
  @bitmask
end

#bitsizeObject (readonly)

Returns the value of attribute bitsize.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def bitsize
  @bitsize
end

#initial_crcObject (readonly)

Returns the value of attribute initial_crc.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def initial_crc
  @initial_crc
end

#nameObject (readonly)

Returns the value of attribute name.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def name
  @name
end

#polynomialObject (readonly)

Returns the value of attribute polynomial.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def polynomial
  @polynomial
end

#reflect_inputObject (readonly) Also known as: reflect_input?

Returns the value of attribute reflect_input.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def reflect_input
  @reflect_input
end

#reflect_outputObject (readonly) Also known as: reflect_output?

Returns the value of attribute reflect_output.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def reflect_output
  @reflect_output
end

#xor_outputObject (readonly)

Returns the value of attribute xor_output.



205
206
207
# File 'lib/crc/_byruby.rb', line 205

def xor_output
  @xor_output
end

Instance Method Details

#acrc(crc, rest_seq = nil, target_crc = 0) ⇒ Object

call-seq:

acrc(crc, rest_seq = nil, target_crc = 0) -> byte string as arc-code

目的となる crc になるように、指定された crc に続くバイト列を逆算します。

出力されるバイト列は、crc のビット数を表現できるバイト数となります。

現在のところ、reflect-input/output 限定となっています。

  • crc32(“123456789????”) の結果が 0 となるような、???? の部分を逆算する

    seq = "123456789"
    seq << CRC::CRC32.acrc(seq)
    p CRC::CRC32[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"
    target_crc = 0x12345678
    seq = seq1 + CRC::CRC32.acrc(seq1, seq2, target_crc) + seq2
    p CRC::CRC32[seq] # => #<CRC::CRC32:12345678>
    

Raises:

  • (NotImplementedError)


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/crc/acrc.rb', line 38

def acrc(crc, rest_seq = nil, target_crc = 0)
  raise NotImplementedError, "crc polynomial is not odd" unless polynomial.odd?
  raise NotImplementedError, "crc module is not reflect input and output" unless reflect_input? && reflect_output?

  bitsize = self.bitsize
  poly = CRC.bitreflect(polynomial, bitsize)
  target_crc = target_crc.to_i
  target_crc ^= xor_output

  if rest_seq
    rest_seq.bytesize.downto(1) do |i|
      target_crc = Aux.acrc_loop_reflect(target_crc, rest_seq.getbyte(i - 1), poly, bitsize, 0xff, 8)
    end
  end

  bytes = (bitsize + 7) / 8
  bits = bytes * 8

  case crc
  when Numeric
    state = bitmask & crc ^ xor_output
  when CRC
    raise "different crc module (given %p(%p), expect %p)" % [crc, crc.class, self] unless variant?(crc)
    state = crc.state
  else
    state = new(crc).state
  end

  if bits > bitsize
    # ビット数が 8 の境界にない場合、その隙間分を埋める。
    # 現在の実装では、最終結果のバイト列における最終バイト値の
    # 上位ビットが 0 であるようにしている。
    pad = bits - bitsize
    target_crc = Aux.acrc_loop_reflect(target_crc, 0, poly, bitsize, 0xff, pad)
  end

  target_crc = Aux.acrc_loop_reflect(target_crc, state, poly, bitsize, bitmask, bitsize)

  bytes.times.reduce("") { |a, *| a << (target_crc & 0xff).chr(Encoding::BINARY); target_crc >>= 8; a }
end

#combine(*args) ⇒ Object

call-seq:

combine(crc1, crc2) -> new combined crc
combine(crc1_int, crc2_int, crc2_len) -> new combined crc


237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/crc.rb', line 237

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) ⇒ Object



199
200
201
# File 'lib/crc.rb', line 199

def crc(seq, crc = nil)
  finish(update(seq, setup(crc)))
end

#digest(seq, crc = nil) ⇒ Object



203
204
205
# File 'lib/crc.rb', line 203

def digest(seq, crc = nil)
  Aux.digest(crc(seq, crc), bitsize)
end

#finish(state) ⇒ Object



194
195
196
197
# File 'lib/crc.rb', line 194

def finish(state)
  state = CRC.bitreflect(state, bitsize) if reflect_input? ^ reflect_output?
  state ^ xor_output
end

#hexdigest(seq, crc = nil) ⇒ Object



207
208
209
# File 'lib/crc.rb', line 207

def hexdigest(seq, crc = nil)
  Aux.hexdigest(crc(seq, crc), bitsize)
end

#inspectObject



285
286
287
# File 'lib/crc.rb', line 285

def inspect
  "#{super}{#{to_str}}"
end

#pretty_inspect(q) ⇒ Object



289
290
291
# File 'lib/crc.rb', line 289

def pretty_inspect(q)
  q.text inspect
end

#setup(crc = nil) ⇒ Object Also known as: init



186
187
188
189
190
# File 'lib/crc.rb', line 186

def setup(crc = nil)
  crc ||= initial_crc
  crc = CRC.bitreflect(crc, bitsize) if reflect_input? ^ reflect_output?
  crc ^ xor_output
end

#to_strObject



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/crc.rb', line 253

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

#variant?(obj) ⇒ Boolean

Returns:

  • (Boolean)


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/crc.rb', line 211

def variant?(obj)
  case
  when obj.kind_of?(CRC)
    mod = obj.class
  when obj.kind_of?(Class) && obj < CRC
    mod = obj
  else
    return false
  end

  if bitsize == mod.bitsize &&
     polynomial == mod.polynomial &&
     reflect_input? == mod.reflect_input? &&
     reflect_output? == mod.reflect_output? &&
     xor_output == mod.xor_output
    true
  else
    false
  end
end