class PageRankr::Ranks::Google::Checksum

Public Class Methods

generate(site) click to toggle source
# File lib/page_rankr/ranks/google/checksum.rb, line 6
def generate(site)
  bytes  = byte_array(site)
  length = bytes.length
  a = b = 0x9E3779B9
  c = 0xE6359A60

  k, len = 0, length
  while(len >= 12)
    a, b, c = mix(*shift(a, b, c, k, bytes))
    k += 12
    len -= 12
  end

  c = c + length

  c = mix(*toss(a, b, c, bytes, len, k))[2]
  "6" + c.to_s
end

Private Class Methods

byte_array(site) click to toggle source
# File lib/page_rankr/ranks/google/checksum.rb, line 27
def byte_array(site)
  bytes = []
  site.each_byte {|b| bytes << b}
  bytes
end
m(v) click to toggle source

Need to keep numbers in the unsigned int 32 range

# File lib/page_rankr/ranks/google/checksum.rb, line 34
def m(v)
  v % 0x100000000
end
mix(a, b, c) click to toggle source
# File lib/page_rankr/ranks/google/checksum.rb, line 46
def mix(a, b, c)
  a, b, c = m(a), m(b), m(c)

  a = m(a-b-c) ^ m(c >> 13)
  b = m(b-c-a) ^ m(a << 8)
  c = m(c-a-b) ^ m(b >> 13)

  a = m(a-b-c) ^ m(c >> 12)
  b = m(b-c-a) ^ m(a << 16)
  c = m(c-a-b) ^ m(b >> 5)

  a = m(a-b-c) ^ m(c >> 3)
  b = m(b-c-a) ^ m(a << 10)
  c = m(c-a-b) ^ m(b >> 15)

  [a, b, c]
end
shift(a, b, c, k, bytes) click to toggle source
# File lib/page_rankr/ranks/google/checksum.rb, line 38
def shift(a, b, c, k, bytes)
  a = m(a + bytes[k + 0] + (bytes[k + 1] << 8) + (bytes[k +  2] << 16) + (bytes[k +  3] << 24))
  b = m(b + bytes[k + 4] + (bytes[k + 5] << 8) + (bytes[k +  6] << 16) + (bytes[k +  7] << 24))
  c = m(c + bytes[k + 8] + (bytes[k + 9] << 8) + (bytes[k + 10] << 16) + (bytes[k + 11] << 24))

  [a, b, c]
end
toss(a, b, c, bytes, len, k) click to toggle source
# File lib/page_rankr/ranks/google/checksum.rb, line 64
def toss(a, b, c, bytes, len, k)
  case len
    when 9..11
      c = c + (bytes[k+len-1] << ((len % 8) * 8))
    when 5..8
      b = b + (bytes[k+len-1] << ((len % 5) * 8))
    when 1..4
      a = a + (bytes[k+len-1] << ((len - 1) * 8))
    else
      return [a, b, c]
  end
  toss(a, b, c, bytes, len-1, k)
end