很多其他语言开发的网站程序需要整合到UCenter中,但是由于 UCenter 是使用
PHP开发的,很难移植。其中最难缠的 uc_authcode.
测试实现了 uc_authcode 函数。纯 python,无三方库。
This work is licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# FileName : uc_authcode.py
# Author : Feather.et.ELF
# Created : Fri Mar 25 00:11:57 2011 by Feather.et.ELF
# Copyright : Feather Workshop (c) 2011
# Description : uc_authcode in python
# Time-stamp: <2011-03-25 00:12:13 andelf>
def uc_authcode(string, op='DECODE', key='', expiry=0):
import time as t
import base64
import hashlib
md5 = lambda s: hashlib.md5(s).hexdigest()
microtime = lambda : str(t.time())
time = lambda : int(t.time())
ckey_length = 4
key = md5(key) # or use key = md5(key or UC_KEY)
keya = md5(key[:16])
keyb = md5(key[16:])
if op == 'DECODE':
keyc = string[:ckey_length]
else:
keyc = md5(microtime())[-ckey_length:]
cryptkey = keya + md5(keya + keyc)
key_length = len(cryptkey)
if op == 'DECODE':
string = base64.b64decode(string[ckey_length:])
else:
string = ('%010d' % (expiry + time() if expiry else 0)) + \
md5(string + keyb)[:16] + string
string_length = len(string)
result = ''
box = range(256)
rndkey = [ord(cryptkey[i % key_length]) for i in xrange(256)]
j = 0
for i in xrange(256):
j = (j + box[i] + rndkey[i]) % 256
box[i], box[j] = box[j], box[i]
a = j = 0
for i in xrange(string_length):
a = (a + 1) % 256
j = (j + box[a]) % 256
box[a], box[j] = box[j], box[a]
result += chr(ord(string[i]) ^ (box[(box[a] + box[j]) % 256]))
if op == 'DECODE':
try:
# use assert to catch misc case
assert (int(result[:10])== 0) or (int(result[:10]) - time()> 0)
if result[10:26] == md5(result[26:] + keyb)[:16]:
return result[26:]
else:
return ''
except:
return ''
else:
return keyc + base64.b64encode(result).replace('=', '')
def test():
APP_KEY = 'x2ta5X12oTz75gbRTMB6gY6thZ7D83'
text = 'this_is_the_string_to_be_encrypted'
print 'text=', text
e = uc_authcode(text, "ENCODE", APP_KEY)
print 'e=', e
e += '='*(len(e) % 4) # must fix padding
assert uc_authcode(e, "DECODE", APP_KEY) == text
print 'rslt=', uc_authcode(e, "DECODE", APP_KEY)
if __name__ == '__main__':
test()