mirror of
				https://github.com/noDRM/DeDRM_tools.git
				synced 2025-10-23 23:07:47 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			91 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # Mobipocket PID calculator v0.2 for Amazon Kindle.
 | |
| # Copyright (c) 2007, 2009 Igor Skochinsky <skochinsky@mail.ru>
 | |
| # History:
 | |
| #  0.1 Initial release
 | |
| #  0.2 Added support for generating PID for iPhone (thanks to mbp)
 | |
| #  0.3 changed to autoflush stdout, fixed return code usage
 | |
| class Unbuffered:
 | |
|     def __init__(self, stream):
 | |
|         self.stream = stream
 | |
|     def write(self, data):
 | |
|         self.stream.write(data)
 | |
|         self.stream.flush()
 | |
|     def __getattr__(self, attr):
 | |
|         return getattr(self.stream, attr)
 | |
| 
 | |
| import sys
 | |
| sys.stdout=Unbuffered(sys.stdout)
 | |
| 
 | |
| import binascii
 | |
| 
 | |
| if sys.hexversion >= 0x3000000:
 | |
|   print "This script is incompatible with Python 3.x. Please install Python 2.6.x from python.org"
 | |
|   sys.exit(2)
 | |
| 
 | |
| letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789"
 | |
| 
 | |
| def crc32(s):
 | |
|   return (~binascii.crc32(s,-1))&0xFFFFFFFF 
 | |
| 
 | |
| def checksumPid(s):
 | |
|   crc = crc32(s)
 | |
|   crc = crc ^ (crc >> 16)
 | |
|   res = s
 | |
|   l = len(letters)
 | |
|   for i in (0,1):
 | |
|     b = crc & 0xff
 | |
|     pos = (b // l) ^ (b % l)
 | |
|     res += letters[pos%l]
 | |
|     crc >>= 8
 | |
| 
 | |
|   return res
 | |
| 
 | |
| 
 | |
| def pidFromSerial(s, l):
 | |
|   crc = crc32(s)
 | |
|   
 | |
|   arr1 = [0]*l
 | |
|   for i in xrange(len(s)):
 | |
|     arr1[i%l] ^= ord(s[i])
 | |
| 
 | |
|   crc_bytes = [crc >> 24 & 0xff, crc >> 16 & 0xff, crc >> 8 & 0xff, crc & 0xff]
 | |
|   for i in xrange(l):
 | |
|     arr1[i] ^= crc_bytes[i&3]
 | |
| 
 | |
|   pid = ""
 | |
|   for i in xrange(l):
 | |
|     b = arr1[i] & 0xff
 | |
|     pid+=letters[(b >> 7) + ((b >> 5 & 3) ^ (b & 0x1f))]
 | |
| 
 | |
|   return pid
 | |
| 
 | |
| def main(argv=sys.argv):
 | |
|   print "Mobipocket PID calculator for Amazon Kindle. Copyright (c) 2007, 2009 Igor Skochinsky"
 | |
|   if len(sys.argv)==2:
 | |
|       serial = sys.argv[1]
 | |
|   else:
 | |
|       print "Usage: kindlepid.py <Kindle Serial Number>/<iPhone/iPod Touch UDID>"
 | |
|       return 1
 | |
|   if len(serial)==16:
 | |
|       if serial.startswith("B"):
 | |
|           print "Kindle serial number detected"
 | |
|       else:
 | |
|           print "Warning: unrecognized serial number. Please recheck input."
 | |
|           return 1
 | |
|       pid = pidFromSerial(serial,7)+"*"
 | |
|       print "Mobipocked PID for Kindle serial# "+serial+" is "+checksumPid(pid)
 | |
|       return 0
 | |
|   elif len(serial)==40:
 | |
|       print "iPhone serial number (UDID) detected"
 | |
|       pid = pidFromSerial(serial,8)
 | |
|       print "Mobipocked PID for iPhone serial# "+serial+" is "+checksumPid(pid)
 | |
|       return 0
 | |
|   else:
 | |
|       print "Warning: unrecognized serial number. Please recheck input."
 | |
|       return 1
 | |
|   return 0
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|   sys.exit(main())
 | 
