Php 注册用户帐户时生成随机字母数字字符串

Php 注册用户帐户时生成随机字母数字字符串,php,wordpress,unique,Php,Wordpress,Unique,我有一个要求,当每个用户在我们的Wordpress网站注册时,为他们生成一个唯一的字母数字字符串 我已经在我的子主题的functions.php文件中添加了以下代码,它工作得很好——它将10个字符的字符串作为token_id存储在usermeta表中 function generate_token_id($length = 10) { $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $result = ''; f

我有一个要求,当每个用户在我们的Wordpress网站注册时,为他们生成一个唯一的字母数字字符串

我已经在我的子主题的functions.php文件中添加了以下代码,它工作得很好——它将10个字符的字符串作为token_id存储在usermeta表中

function generate_token_id($length = 10) {
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $result = '';
    for ($i = 0; $i < $length; ++$i) {
        $result .= $characters[mt_rand(0, strlen($characters) - 1)];
        }
    return $result;
}

add_action('user_register', 'save_token_id', 10, 2);

function save_token_id($user_id) {
    $meta_key = "token_id";
    $key = generate_token_id();
    update_user_meta($user_id, $meta_key, $key);
}
但是,PHP调试日志中充满了SQL错误

WordPress database error: [Unknown column '74TTW1PIPP' in 'where clause']
select count(*) from wp_usermeta where meta_value = 74TTW1PIPP

WordPress database error: [Unknown column 'CST10WY8EQ' in 'where clause']
select count(*) from wp_usermeta where meta_value = CST10WY8EQ

WordPress database error: [Unknown column 'M3GSGAHD5J' in 'where clause']
select count(*) from wp_usermeta where meta_value = M3GSGAHD5J
我已经在phpMyAdmin中验证了SQL查询,但是在PHP函数中无法获得正确的SQL查询。meta_值列是明确声明的,为什么它使用$key变量作为列?

而不是$wpdb->get_结果使用$wpdb->get_变量


我不这样认为,如果您使用任何可以生成加密安全哈希字符串的函数,那么您就不需要额外检查数据库中现有的生成的重复密钥。例如,您可以考虑通过将$UrSyID传递给函数来获得一个唯一的哈希键。
<?php
/**
 * Generate cryptographically secure hashed string
 *
 * @param int|string $user_id
 * @param int $length
 * @param string $hash Any cryptographically secure hash
 * For example: 'gost-crypto', 'whirlpool', 'ripemd128' and for more
 * checkout https://www.php.net/manual/en/function.hash-algos.php
 *
 * @param int $iterations The number of internal iterations to perform for the derivation
 * @return string
 */
function generate_unique_id($user_id, $length = 20, $hash = 'ripemd128', $iterations = 10000) {
    // Generate a random IV
    if (version_compare(PHP_VERSION, '7.0.0', '<')) {
        $salt = openssl_random_pseudo_bytes(16);
    } else {
        $salt = random_bytes(16);
    }

    return hash_pbkdf2($hash, $user_id, $salt, $iterations, $length);
}

// Assuming 1 is the user ID
echo generate_unique_id(1);

在这种情况下,它并不重要,因为它只得到一个整数,表示存储行的数量。或者,使用随机整数而不是mt随机数;后者不是加密随机生成器,这意味着它可以生成可预测的ID。另请参阅。感谢您发布此消息,我在研究此解决方案时确实阅读了您的链接线程,并决定反对此实现。从我所看到的,大多数加密生成的字符串是十六进制的,这意味着有16分之一的重复机会,而上面的alphenumeric字符串是36分之一。此外,我实际上只需要7或8个字符,而不是20+,因此冲突的可能性也会增加,特别是对于十六进制,我通过在保存之前检查生成的字符串是否存在来说明这一点。然而,SQL检查是我无法工作的一部分。好吧,我不同意这一点,即冲突的可能性。因为我编写的函数将每个用户ID作为参数,这必须是唯一的,并根据用户ID为您提供Crytographic secure unique hash。因为用户ID是唯一的,所以生成的hash应该是唯一的。hash_pbkdf2函数返回十六进制字符,它缺少G-Z作为输出-即每个组合增加20个字符选项16对36。我了解加密的工作原理,我只需要7个字符,所以36^7提供的组合比16^7更多。在某种程度上,如果我只为加密函数使用7个字符,就会出现重复/冲突,因此我选择使用字母数字组合,并在do/while循环中添加sql验证。我想我明白了:
WordPress database error: [Unknown column '74TTW1PIPP' in 'where clause']
select count(*) from wp_usermeta where meta_value = 74TTW1PIPP

WordPress database error: [Unknown column 'CST10WY8EQ' in 'where clause']
select count(*) from wp_usermeta where meta_value = CST10WY8EQ

WordPress database error: [Unknown column 'M3GSGAHD5J' in 'where clause']
select count(*) from wp_usermeta where meta_value = M3GSGAHD5J
 $keycheck = $wpdb->get_var("select count(*) from `usermeta` where `meta_value` like '"$key"'");
}
<?php
/**
 * Generate cryptographically secure hashed string
 *
 * @param int|string $user_id
 * @param int $length
 * @param string $hash Any cryptographically secure hash
 * For example: 'gost-crypto', 'whirlpool', 'ripemd128' and for more
 * checkout https://www.php.net/manual/en/function.hash-algos.php
 *
 * @param int $iterations The number of internal iterations to perform for the derivation
 * @return string
 */
function generate_unique_id($user_id, $length = 20, $hash = 'ripemd128', $iterations = 10000) {
    // Generate a random IV
    if (version_compare(PHP_VERSION, '7.0.0', '<')) {
        $salt = openssl_random_pseudo_bytes(16);
    } else {
        $salt = random_bytes(16);
    }

    return hash_pbkdf2($hash, $user_id, $salt, $iterations, $length);
}

// Assuming 1 is the user ID
echo generate_unique_id(1);