Module: Kindle::DRM
- Defined in:
- lib/kindle/drm.rb
Constant Summary collapse
- LETTERS =
"ABCDEFGHIJKLMNPQRSTUVWXYZ123456789".split(//)
Instance Method Summary collapse
-
#checksumPid(s) ⇒ Object
Generates the actual Personal ID (PID) needed to tie/untie content (such as .mobi/.azw files) to a specific device.
-
#crc32(s) ⇒ Object
Special cyclical redundancy check (checksumming) function.
- #serialToDeviceTypeAndPidSize(serial) ⇒ Object
-
#serialToIntermediaryPid(s, l) ⇒ Object
Figures out the intermediary Personal ID (PID) of a device based on its serial number and expected length of the output.
- #serialToPid(serial) ⇒ Object
Instance Method Details
#checksumPid(s) ⇒ Object
Generates the actual Personal ID (PID) needed to tie/untie content (such as .mobi/.azw files) to a specific device.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/kindle/drm.rb', line 16 def checksumPid(s) tmp = crc32(s) crc = tmp ^ (tmp >> 16) res = s l = LETTERS.length for i in 0..1 do b = crc & 0xFF t = b.divmod(l)[0] pos = t ^ (b % l) res = "#{res}#{LETTERS[pos % l]}" crc >>= 8 end res end |
#crc32(s) ⇒ Object
Special cyclical redundancy check (checksumming) function.
10 11 12 |
# File 'lib/kindle/drm.rb', line 10 def crc32(s) (~Zlib.crc32(s, -1)) & 0xFFFFFFFF end |
#serialToDeviceTypeAndPidSize(serial) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/kindle/drm.rb', line 58 def serialToDeviceTypeAndPidSize(serial) type = nil size = nil pad = nil l = serial.length if l == 16 case serial[0, 4] when /^B001/ type = "Kindle 1" when /^B101/ type = "Kindle 1" when /^B002/ type = "Kindle 2" when /^B003/ type = "Kindle 2 International" when /^B004/ type = "Kindle DX" when /^B005/ type = "Kindle DX 2" when /^B009/ type = "Kindle DX International 2 (Graphite)" when /^B/ type = "Unknown Kindle model. Please report!" end size = 7 pad = '*' elsif l == 40 type = "iPhone" size = 8 end return nil if type.nil? || size.nil? return [type, size, pad] end |
#serialToIntermediaryPid(s, l) ⇒ Object
Figures out the intermediary Personal ID (PID) of a device based on its serial number and expected length of the output. Apparently this varies by the type of device.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/kindle/drm.rb', line 34 def serialToIntermediaryPid(s, l) crc = crc32(s) arr1 = Array.new(l, 0) for i in 0..(s.length - 1) do code = s[i] code = code.ord if code.class == String # Fix for Ruby 1.9+ arr1[i%l] ^= code end # Grab each CRC byte and OR with a portion of the crc_bytes = [crc >> 24 & 0xff, crc >> 16 & 0xff, crc >> 8 & 0xff, crc & 0xff] for i in 0..(l - 1) do arr1[i] ^= crc_bytes[i&3] end pid = "" for i in 0..(l-1) do b = arr1[i] & 0xff pid += LETTERS[(b >> 7) + ((b >> 5 & 3) ^ (b & 0x1f))] end pid end |
#serialToPid(serial) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/kindle/drm.rb', line 95 def serialToPid(serial) pid = nil type, size, pad = serialToDeviceTypeAndPidSize(serial) if type.nil? # No dice.. :( else ipid = serialToIntermediaryPid(serial, size) ipid += pad unless pad.nil? pid = checksumPid(ipid) end pid end |