PHP许可证密钥生成器

4

我希望能够通过PHP脚本生成许可证密钥,并将其传输到我的应用程序(Air,AS3),然后在该应用程序中正确读取数据。例如,以下是代码:

<?php
  error_reporting(E_ALL);
  function KeyGen(){
     $key = md5(mktime());
     $new_key = '';
     for($i=1; $i <= 25; $i ++ ){
               $new_key .= $key[$i];
               if ( $i%5==0 && $i != 25) $new_key.='-';
     }
  return strtoupper($new_key);
  }
  echo KeyGen();
?>

生成的密钥类似于这样:1AS7-09BD-96A1-CC8D-F106。我想在密钥中添加一些信息,例如电子邮件用户,然后将其传递给客户端(Air应用程序),解密数据并在应用程序中显示。这是否可能?

嗯,这并不是那么容易的事情,你需要拥有属于序列号所有者的特定数据才能使它们变得独一无二。 - RobertPitt
需要将多少字节的数据存储到“key”中? - hakre
@hakre。我不知道它将有多少字节...我需要传递电子邮件地址(someclientmail@gmail.com),当前日期,一对随机数(用于在应用程序上检查 - 这是密钥有效性的最简单测试)。 - Astraport
1
MD5是一种哈希函数,而不是加密/解密类型的函数。但是您可以使用base64进行“编码”(也许是加密),然后进行“解码”(在您的用途中是解密)。它很容易被破解(只是说一下),但如果它能够完成工作,为什么不使用它呢?请分享更多的问题,以便更突出您实际寻找的内容。您在实现时有问题吗?您需要额外的加密/解密函数,这些函数在AS3和PHP中都存在吗? - hakre
2
这样怎么样:在密钥中哈希电子邮件地址加上一些秘密。将该MD5哈希传递给您的应用程序并存储在数据库中。在与数据库验证后,在响应中返回用户信息。让应用程序将其存储以供以后显示。 - hakre
显示剩余7条评论
4个回答

3

好的,让我们分解一下您的要求:

您想要:

  1. 向密钥添加一些信息
    那么您想要添加什么信息呢?在这样做时,您想要让密钥变长吗?您希望此信息需要一个密钥才能解密吗?从最基本的意义上讲,PHP可以实现。
  2. 给用户发送电子邮件
    PHP有一个mail()函数。它几乎可以直接使用。
  3. 然后将其传递给客户端(Air应用程序)
    Air应用程序是否通过HTTP请求调用此PHP脚本?如果是,请设置内容类型并向其输出密钥。
  4. 解密数据 回到第1点,这是可能的,但您是否需要密钥,您是否关心格式是否更改。此外,您不想在AS3应用程序中解密数据吗?
  5. 在应用程序中显示。 如果AS3应用程序将显示密钥或解密后的数据,则需要在AS3中获取数据以显示它。

谢谢Justin。1. 我需要传递电子邮件地址(someclientmail@gmail.com),当前日期,一对随机数(用于检查应用程序的有效性 - 这是最简单的测试)。2. 哦不,我不需要这个功能。我需要将电子邮件保存在数据库中。3. 这就是我所知道和能做的全部。4. 我可以使用PHP&AS3 - 例如base64和MD5。5. 例如显示电子邮件。 - Astraport

2

如果您只想存储一些信息,但是要使用上面使用的符号集(0-9A-Z)"编码"它,您可以使用以下算法。

这个代码是我写的一个古老的 Python (3) 程序。它肯定不会很花哨,也没有经过很多测试,但我认为它比没有答案要好。将代码移植到 PHP 或 AS 应该非常容易。例如,reduce 语句可以用命令式风格的循环替换。还要注意,在 Python 中 // 表示整数除法。

还应该很容易地将一些压缩/加密功能添加到其中。希望它类似于您想要的。下面开始。

from functools import reduce

class Coder:
    def __init__(self, alphabet=None, groups=4):
        if not alphabet:
            alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        self.alphabet = alphabet
        self.groups = groups

    def encode(self, txt):
        N = len(self.alphabet)
        num = reduce(lambda x,y: (x*256)+y, map(ord, txt))

        # encode to alphabet
        a = []
        while num > 0:
            i = num % N
            a.append(self.alphabet[i])
            num -= i
            num = num//N

        c = "".join(a)
        if self.groups > 0:
            # right zero pad
            while len(c) % self.groups != 0:
                c = c + self.alphabet[0]
            # make groups
            return '-'.join([c[x*self.groups:(x+1)*self.groups]
                             for x in range(len(c)//self.groups)])
        return c

    def decode(self, txt, separator='-'):
        # remove padding zeros and separators
        x = txt.rstrip(self.alphabet[0])
        if separator != None:
            x = x.replace(separator, '')
        N = len(self.alphabet)
        x = [self.alphabet.find(c) for c in x]
        x.reverse()
        num = reduce(lambda x,y: (x*N)+y, x)

        a = []
        while num > 0:
            i = num % 256
            a.append(i)
            num -= i
            num = num//256
        a.reverse()
        return ''.join(map(chr, a))

if __name__ == "__main__":
    k = Coder()
    s = "Hello world!"
    e = k.encode(s)
    print("Encoded:", e)
    d = k.decode(e)
    print("Decoded:", d)

示例输出:
Encoded: D1RD-YU0C-5NVG-5XL8-7620
Decoded: Hello world!

1
使用MD5是无法实现此功能的,因为这是一种单向哈希。您应该使用解密方法来实现,因为它使用密钥进行编码和解码。有几个PHP扩展可以做到这一点,请参考PHP手册。您也可以使用第三方软件来实现,例如http://wwww.phplicengine.com

0

我使用Python找到了Andre's answer的价值。

与提问者一样,我需要一个php解决方案,所以我将安德烈的代码改写为PHP。如果有人觉得有用,我在这里发布它。

然而,它存在着与Python版本不同的限制:

似乎无法编码任何大于8个字符的字符串。这可能是可以解决的问题?这与PHP如何处理非常大的整数有关。幸运的是,对于我的用例,我只需要编码少于8个字符。它可能在不同的环境下工作,我不确定。总之,在声明这一警告后,这是该类:

<?php

/**
 * Basic key generator class based on a simple Python solution by André Laszlo.
 * It's probably not secure in any way, shape or form. But may be suitable for
 * your requirements (as it was for me).
 *
 * Due to limitations with PHP's processing of large integers, unlike the Python
 * app, only a small amount of data can be encoded / decoded. It appears to
 * allow a maximum of 8 unencoded characters.
 *
 * The original Python app is here: https://dev59.com/T1jUa4cB1Zd3GeqPTqwE#6515005
 */

class KeyGen
{
    /**
     * @var array
     */
    protected $alphabet;

    /**
     * @var int
     */
    protected $groups;

    /**
     * @var string
     */
    protected $separator;

    /**
     * Controller sets the alphabet and group class properties
     *
     * @param  string $alphabet
     * @param  int $groups
     * @param  string $separator
     */
    public function __construct(string $alphabet = null, int $groups = 4, string $separator = '-')
    {
        $alphabet = $alphabet ?: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $this->alphabet = str_split($alphabet);
        $this->groups = $groups;
        $this->separator = $separator;
    }

    /**
     * Encodes a string into a typical license key format
     *
     * @param  string $txt
     * @return string
     */
    public function encode(string $txt)
    {
        // calculate the magic number
        $asciiVals = array_map('ord', str_split($txt));
        $num = array_reduce($asciiVals, function($x, $y) {
            return ($x * 256) + $y;
        });

        // encode
        $a = [];
        $i = 0;
        $n = count($this->alphabet);
        while ($num > 0) {
            $i = $num % $n;
            array_push($a, $this->alphabet[$i]);
            $num -= $i;
            $num = intdiv($num, $n);
        }

        // add padding digits
        $str = implode('', $a);
        if($this->groups > 0) {
            while (strlen($str) % $this->groups != 0) {
                $str .= $this->alphabet[0];
            }
        }

        // split into groups
        if($this->groups) {
            $split = str_split($str, $this->groups);
            $str = implode($this->separator, $split);
        }

        return $str;
    }

    /**
     * Decodes a license key
     *
     * @param  string $txt
     * @return string
     */
    public function decode(string $txt)
    {
        // remove separators and padding
        $stripped = str_replace($this->separator, '', $txt);
        $stripped = rtrim($stripped, $this->alphabet[0]);

        // get array of alphabet positions
        $alphabetPosistions = [];
        foreach(str_split($stripped) as $char){
            array_push($alphabetPosistions, array_search($char, $this->alphabet));
        }

        // caluculate the magic number
        $alphabetPosistions = array_reverse($alphabetPosistions);
        $num = array_reduce($alphabetPosistions, function($x, $y) {
            $n = count($this->alphabet);
            return ($x * $n) + $y;
        });

        // decode
        $a = [];
        $i = 0;
        $n = count($this->alphabet);
        while ($num > 0) {
            $i = $num % 256;
            array_push($a, $i);
            $num -= $i;
            $num = intdiv($num, 256);
        }

        return implode('', array_map('chr', array_reverse($a)));
    }

}

以下是一个使用示例,对"ABC123"进行编码和解码:

$keyGen = new KeyGen();

$encoded = $keyGen->encode('ABC123'); //returns 3WJU-YSMF-P000

$decoded = $keyGen->decode('3WJU-YSMF-P000'); //returns ABC123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接