Chinaunix首页 | 论坛 | 博客
  • 博客访问: 235471
  • 博文数量: 32
  • 博客积分: 1971
  • 博客等级: 上尉
  • 技术积分: 390
  • 用 户 组: 普通用户
  • 注册时间: 2004-10-15 12:54
文章分类

全部博文(32)

文章存档

2012年(6)

2011年(19)

2009年(7)

分类: Python/Ruby

2011-02-24 12:14:49

在网友bingo的帮助下,找到了可以在python下使用的TEA加解密算法,同时我查了一下,这个算法是MIT授权,简单来说就是随便用随便改。
经过测试,这个算法是线程安全的,这样我终于能解决我的程序中令人头疼的加解密问题了。
我把整个加解密算法打包到一个类中,如果有谁要用,引用起来很方便,直接抄我的代码就行了。
代码如下:
  1. #!/usr/bin/python
  2. #-*- coding:utf-8-*-
  3. import Queue, threading, sys, os
  4. import time

  5. import binascii
  6. import struct

  7. # working thread
  8. class Worker(threading.Thread):
  9.     worker_count = 0
  10.     def __init__( self, workQueue, resultQueue, timeout = 0, **kwds):
  11.         threading.Thread.__init__( self, **kwds )
  12.         self.id = Worker.worker_count
  13.         Worker.worker_count += 1
  14.         self.setDaemon( True )
  15.         self.workQueue = workQueue
  16.         self.resultQueue = resultQueue
  17.         self.timeout = timeout
  18.         self.start( )

  19.     def run( self ):
  20.         ''' the get-some-work, do-some-work main loop of worker threads '''
  21.         while True:
  22.             try:
  23.                 callable, args, kwds = self.workQueue.get(timeout=self.timeout)
  24.                 res = callable(*args, **kwds)
  25.                 print "worker[%2d]: %s" % (self.id, str(res) )
  26.                 self.resultQueue.put( res )
  27.             except Queue.Empty:
  28.                 break
  29.             except :
  30.                 print 'worker[%2d]' % self.id, sys.exc_info()[:2]
  31.                
  32. class WorkerManager:
  33.     def __init__( self, num_of_workers=10, timeout = 1):
  34.         self.workQueue = Queue.Queue()
  35.         self.resultQueue = Queue.Queue()
  36.         self.workers = []
  37.         self.timeout = timeout
  38.         self._recruitThreads( num_of_workers )

  39.     def _recruitThreads( self, num_of_workers ):
  40.         for i in range( num_of_workers ):
  41.             worker = Worker( self.workQueue, self.resultQueue, self.timeout )
  42.             self.workers.append(worker)

  43.     def wait_for_complete( self):
  44.         # ...then, wait for each of them to terminate:
  45.         while len(self.workers):
  46.             worker = self.workers.pop()
  47.             worker.join( )
  48.             if worker.isAlive() and not self.workQueue.empty():
  49.                 self.workers.append( worker )
  50.         print "All jobs are are completed."

  51.     def add_job( self, callable, *args, **kwds ):
  52.         self.workQueue.put( (callable, args, kwds) )
  53.     
  54.     def get_result( self, *args, **kwds ):
  55.         return self.resultQueue.get( *args, **kwds )



  56. def test_job(id, sleep = 0.001 ):
  57.     try:
  58.         result = _3ds.encrypt('中文测hel试lo wor!·*#J&^FD*mv2ld')
  59.         result1 = _3ds.decrypt(result)
  60.         print id, result,result1
  61.     except:
  62.         print '[%4d]' % id, sys.exc_info()[:2]
  63.     return id

  64. def test():
  65.     import socket
  66.     socket.setdefaulttimeout(10)
  67.     print 'start testing'
  68.     wm = WorkerManager(10)
  69.     for i in range(100):
  70.         wm.add_job( test_job, i, i*0.001 )
  71.     wm.wait_for_complete()
  72.     print 'end testing'

  73. class _secret():
  74.     """TEA 加解密, 64比特明码, 128比特密钥
  75. 这个加解密算法是MIT授权,被授权人有权利使用、复制、修改、合并、出版发行、散布、再授权及
  76. 贩售软件及软件的副本。
  77. 这是一个确认线程安全的独立加密模块,使用时必须要有一个全局变量secret_key,要求大于等于16位
  78.     """

  79.     def xor(self,a, b):
  80.         op = 0xffffffffL
  81.         a1,a2 = struct.unpack('>LL', a[0:8])
  82.         b1,b2 = struct.unpack('>LL', b[0:8])
  83.         return struct.pack('>LL', ( a1 ^ b1) & op, ( a2 ^ b2) & op)
  84.     
  85.     def code(self,v, k):
  86.         n=16
  87.         op = 0xffffffffL
  88.         delta = 0x9e3779b9L
  89.         k = struct.unpack('>LLLL', k[0:16])
  90.         y, z = struct.unpack('>LL', v[0:8])
  91.         s = 0
  92.         for i in xrange(n):
  93.             s += delta
  94.             y += (op &(z<<4))+ k[0] ^ z+ s ^ (op&(z>>5)) + k[1]
  95.             y &= op
  96.             z += (op &(y<<4))+ k[2] ^ y+ s ^ (op&(y>>5)) + k[3]
  97.             z &= op
  98.         r = struct.pack('>LL',y,z)
  99.         return r

  100.     def decipher(self,v, k):
  101.         n = 16
  102.         op = 0xffffffffL
  103.         y, z = struct.unpack('>LL', v[0:8])
  104.         a, b, c, d = struct.unpack('>LLLL', k[0:16])
  105.         delta = 0x9E3779B9L
  106.         s = (delta << 4)&op
  107.         for i in xrange(n):
  108.             z -= ((y<<4)+c) ^ (y+s) ^ ((y>>5) + d)
  109.             z &= op
  110.             y -= ((z<<4)+a) ^ (z+s) ^ ((z>>5) + b)
  111.             y &= op
  112.             s -= delta
  113.             s &= op
  114.         return struct.pack('>LL', y, z)

  115.     def encrypt(self,v):
  116.         END_CHAR = '\0'
  117.         FILL_N_OR = 0xF8
  118.         vl = len(v)
  119.         filln = (8-(vl+2))%8 + 2
  120.         fills = ''
  121.         for i in xrange(filln):
  122.             fills = fills + chr(220)
  123.         v = ( chr((filln -2)|FILL_N_OR)
  124.               + fills
  125.               + v
  126.               + END_CHAR * 7)
  127.         tr = '\0'*8
  128.         to = '\0'*8
  129.         r = ''
  130.         o = '\0' * 8
  131.         for i in xrange(0, len(v), 8):
  132.             o = self.xor(v[i:i+8], tr)
  133.             tr = self.xor( self.code(o, secret_key), to)
  134.             to = o
  135.             r += tr
  136.         return r
  137.     
  138.     def decrypt(self,v):
  139.         l = len(v)
  140.         prePlain = self.decipher(v, secret_key)
  141.         pos = (ord(prePlain[0]) & 0x07L) +2
  142.         r = prePlain
  143.         preCrypt = v[0:8]
  144.         for i in xrange(8, l, 8):
  145.             x = self.xor(self.decipher(self.xor(v[i:i+8], prePlain),secret_key ), preCrypt)
  146.             prePlain = self.xor(x, preCrypt)
  147.             preCrypt = v[i:i+8]
  148.             r += x
  149.         if r[-7:] != '\0'*7:
  150.             return None
  151.         return r[pos+1:-7]

  152. if __name__ == '__main__':
  153.     global secret_key
  154.     secret_key = binascii.b2a_base64('ddfevzdfewrtgd34243fsfs')
  155.     _3ds = _secret()

  156.     print secret_key

  157.     test()

代码解释:
前面import的binascii和struct不要少,必须要有一个全局变量secret_key,要求必须大于等于16位字符,另外我改了一些原TEA算法中的一些地方。
使用很简单,申明类后,直接用_3ds.encrypt('字串')加密,或者用_3ds.decrypt('密文')解密就行了。


阅读(8813) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~