PHP暗号解読アルゴリズムauthcodeをPythonで書き換える


Discuzシリーズの製品で広く使われている暗号解読アルゴリズムauthcodeを一度読んだばかりで、利益が得られ、巧みに設計されています.
その中の考えを本当に理解するために、Pythonで書き直しました.白プログラマーは1枚で、学芸が精巧ではありません.通りかかった大侠の皆さんがもっと教えてくれることを望んでいます.
PS:法的な面では,元のアルゴリズムの使用が制限されているかどうかは不明である.原文:CatRollスタジオ
Pythonコード:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import time
import base64
import hashlib


class AuthCode(object):

    @classmethod
    def encode(cls, string, key, expiry=0):
        """
          
        @param string:       
        @param key:   
        @return:     
        """
        return cls._auth_code(string, 'ENCODE', key, expiry)

    @classmethod
    def decode(cls, string, key, expiry=0):
        """
          
        @param string:       
        @param key:   
        @return:     
        """
        return cls._auth_code(string, 'DECODE', key, expiry)

    @staticmethod
    def _md5(source_string):
        return hashlib.md5(source_string).hexdigest()

    @classmethod
    def _auth_code(cls, input_string, operation='DECODE', key='', expiry=3600):
        """
          /  
        @param input_string:       
        @param operation:   (      ,     )
        @param key:   
        @param expiry:      ,    ,0       
        @return:            base64_encode       
        """

        # -----------------------        -----------------------

        rand_key_length = 4
        #           0-32
        #           ,            ,          ,      
        #    ,        ,     = 16   ckey_length   ,    0,        

        key = cls._md5(key)
        key_a = cls._md5(key[:16])
        key_b = cls._md5(key[16:])
        if rand_key_length:
            if operation == 'DECODE':
                key_c = input_string[:rand_key_length]
            else:
                key_c = cls._md5(str(time.time()))[-rand_key_length:]
        else:
            key_c = ''

        crypt_key = key_a + cls._md5(key_a + key_c)

        if operation == 'DECODE':
            handled_string = base64.b64decode(input_string[rand_key_length:])
        else:
            expiration_time = expiry + int(time.time) if expiry else 0
            handled_string = '%010d' % expiration_time + cls._md5(input_string + key_b)[:16] + input_string

        rand_key = list()
        for i in xrange(256):
            rand_key.append(ord(crypt_key[i % len(crypt_key)]))

        # ----------------------------------------------------------

        box = range(256)
        j = 0
        for i in xrange(256):
            j = (j + box[i] + rand_key[i]) % 256
            tmp = box[i]
            box[i] = box[j]
            box[j] = tmp

        #for i in xrange(len(box)):
        #    print str(box[i]).rjust(5),
        #    if ((i + 1) % 10) == 0:
        #        print ''

        result = ''
        a = 0
        j = 0
        for i in xrange(len(handled_string)):
            a = (a + 1) % 256
            j = (j + box[a]) % 256
            tmp = box[a]
            box[a] = box[j]
            box[j] = tmp
            result += chr(ord(handled_string[i])^(box[(box[a]+box[j])%256]))

        if operation == 'DECODE':
            if (int(result[:10]) == 0 or (int(result[:10]) - time.time() > 0)) and \
                    (result[10:26] == cls._md5(result[26:] + key_b)[:16]):
                output_string = result[26:]
            else:
                output_string = ''
        else:
            output_string = key_c + base64.b64encode(result)

        return output_string

if __name__ == '__main__':
    src = 'My name is Hu Ang, I\'m a programmer.'
    key = 'fr1e54b8t4n4m47'
    encoded_string = AuthCode.encode(src, key)
    decoded_string = AuthCode.decode(encoded_string, key)
    print 'Source String:', src
    print 'After Encode :', encoded_string
    print 'After Decode :', decoded_string
    print '----------------------------------------------'
    #    PHP            ,    Python   
    # $source_string = "My name is Hu Ang.";
    # $secret_key = 'fr1e54b8t4n4m47';
    # $encoded_string = authcode($source_string, 'ENCODE', $secret_key, 0);
    php_encoded_string = '82798mEQ6ouQo1rFrbSXT5EHVjZ0gH0WuuZDXd9us/q44JAhmPwBAFZqvwXhvnjgUOJ+5aYh5ed8zNL3cjTOGBY='
    print 'Decode string encoded via php:', AuthCode.decode(php_encoded_string, key)
    # PS:Python             PHP       。

PHPコード:
<?php

class AuthCode {

    public static function encode($str, $key) {
        return self::_auth_code($str, 'ENCODE', $key, 0);
    }

    public static function decode($str, $key) {
        return self::_auth_code($str, 'DECODE', $key, 0);
    }

    public static function _auth_code($string, $operation = 'DECODE', $key = '', $expiry = 3600) {
        /***
         *           0-32;
         *       ,          ,            ,          ,      。
         *     ,        ,     = 16   $ckey_length   
         *      0  ,        
         */
        $ckey_length = 4;
        
        $key = md5($key);
        $keya = md5(substr($key, 0, 16));
        $keyb = md5(substr($key, 16, 16));
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

        $cryptkey = $keya.md5($keya.$keyc);
        $key_length = strlen($cryptkey);

        $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
        $string_length = strlen($string);

        $result = '';
        $box = range(0, 255);

        $rndkey = array();
        for($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }

        for($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }

        for($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }

        if($operation == 'DECODE') {
            if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
                return substr($result, 26);
            } else {
                return '';
            }
        } else {
            return $keyc.base64_encode($result);
        }
    }

}

$source_string = "My name is Hu Ang, I'm a programmer.";
$secret_key = 'fr1e54b8t4n4m47';
echo 'Source String: ' . $source_string . "
"; $encoded_string = AuthCode::encode($source_string, $secret_key); echo 'After Encode : ' . $encoded_string . "
"; $decoded_string = AuthCode::decode($encoded_string, $secret_key); echo 'After Decode : ' . $decoded_string . "
"; echo "----------------------------------------------
"; $python_encoded_string = "88fcnCU6Wb+6LPREpYrhB3NcKS3OU+V8FqQ4uUklvZR170HWlyBLtPKEtP9Ui/qZp1ZqEhF9f5k6XBDixsVgEKk="; echo 'Decode string encoded via python: ' . AuthCode::decode($python_encoded_string, $secret_key);