andelf fledna Feather

2011年3月25日星期五

uc_authcode 函数的 Python 实现.

很多其他语言开发的网站程序需要整合到UCenter中,但是由于 UCenter 是使用
PHP开发的,很难移植。其中最难缠的 uc_authcode.
测试实现了 uc_authcode 函数。纯 python,无三方库。

Creative Commons License
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()

1 条评论:

smalltalk 说...

this is very cool