Хорошая практика для создания уникальных идентификаторов уникальных идентификаторов человека

Мне нужно создать уникальный идентификатор для наших пользователей. Я не хочу использовать идентификатор auto_incrementing, потому что я не хочу, чтобы пользователи могли угадать, сколько у нас пользователей или что такое темпы роста.

UUID тоже не является вариантом, потому что пользователям придется повторно вводить идентификатор на смартфоне.

Поэтому я надеюсь, что смогу уменьшить «грубую форсирующую» базу данных, чтобы найти неиспользуемые идентификаторы. Что было бы разумным путем?

Спасибо!

Создайте список случайных номеров uniqe (вы можете использовать функции range() и shuffle() PHP и хранить их в базе данных или даже в txt-файле. Убедитесь, что список достаточно длинный, так что он длится некоторое время. Затем, когда вам нужен новый идентификатор, просто введите первое значение из списка.

 $list = range(0,999999); //list now contains numbers from 0 to 999999 // if you ever need to add more ID's to your list, start at 1000000. shuffle($list); //now it's randomly ordered 

Хорошо, я попробую еще раз. Ваши цели:

  • обфускация скорости приращения вашего идентификатора – не последовательная, не угадаемая, не рассчитанная
  • они все еще «пригодны для использования» для пользователей смартфонов, поэтому длинные UUID или хэши SHA1 выходят за рамки
  • избегать необходимости случайных догадок / брутфорсских приказах к базе данных
  • все еще имеют хорошую производительность базы данных с вашими внешними ключами

Чтобы по-прежнему иметь хорошую производительность в вашей базе данных, вы должны сохранить стандартное число auto_incrementing для вашего ПК. Обратите внимание, что InnoDB заказывает строки на основе PK (см. « Индекс кластеризации InnoDB »), поэтому, если вы используете какой-то магический хеш в качестве ПК, вы получите много переупорядочения в вашем кластерном индексе, что даст плохую производительность записи.

Я предлагаю использовать алгоритм шифрования (шифрование, а не хеширование) для шифрования и расшифровки идентификатора, который вы хотите запутать. Кроме того, для лучшей обфускации вы хотите использовать минимальную длину для полученной строки. Полученная строка должна быть все еще пригодной для использования, поэтому вы должны использовать что-то вроде base64, чтобы представить ее читаемой пользователем.

Попробуйте этот пример шифрования:

 function my_number_encrypt($data, $key, $base64_safe=true, $minlen=8) { $data = base_convert($data, 10, 36); $data = str_pad($data, $minlen, '0', STR_PAD_LEFT); $data = @mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC); if ($base64_safe) $data = str_replace('=', '', base64_encode($data)); return $data; } function my_number_decrypt($data, $key, $base64_safe=true) { if ($base64_safe) $data = base64_decode($data.'=='); $data = @mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC); $data = base_convert($data, 36, 10); return $data; } $key = "my super secret magic bytes"; $id = 12345678; // obtain_normal_key_from_mysql(); // give ID to user $enc = my_number_encrypt($i, $key); // get ID from user $dec = my_number_decrypt($enc, $key); // fetch from database using normal ID -> 12345678 // demo code for($i=10000; $i<10050; $i++) { $enc = my_number_encrypt($i, $key); $dec = my_number_decrypt($enc, $key); echo "$i -> $enc -> $dec", PHP_EOL; } 

Демо-результат:

 10000 -> 1RXK468NYes -> 10000 10001 -> QdEov5mjMPA -> 10001 10002 -> 2gsgzWJgD+8 -> 10002 10003 -> 2zwPwhqr9HI -> 10003 10004 -> Xq+kDh1UFuM -> 10004 10005 -> wfwv6TrW9xY -> 10005 10006 -> 1Lck1L0HJ/U -> 10006 10007 -> v+3YY2zfL1A -> 10007 10008 -> 5AmGlqD8byM -> 10008 10009 -> pZBIpPnKXHU -> 10009 10010 -> CAeWdKGkk8c -> 10010 10011 -> fYddnLOSK6U -> 10011 10012 -> na8Ry0erHv8 -> 10012 10013 -> zxNj+ZJVMBY -> 10013 10014 -> gWJWC9VulZc -> 10014 10015 -> 5pR9B79eM/E -> 10015 10016 -> MQtpBhpzHRA -> 10016 10017 -> dW+3nejBEIg -> 10017 10018 -> znB/feM6104 -> 10018 10019 -> RtdRwwRyEcs -> 10019 10020 -> 4cW/OWT140E -> 10020 10021 -> dIvK9VjOevg -> 10021 10022 -> QxLdfrucc/Y -> 10022 10023 -> M0KN3sX10Gs -> 10023 10024 -> 827yFJyDCG4 -> 10024 10025 -> JF/VRj92qL8 -> 10025 10026 -> IXTvn/SCzek -> 10026 10027 -> L4nFwvhgwX8 -> 10027 10028 -> z0lve9nhgDA -> 10028 10029 -> m/UBgZzfIXo -> 10029 10030 -> IfWcrLKTHXk -> 10030 10031 -> n/jPFwKR/9A -> 10031 10032 -> j1mm2kbeWl0 -> 10032 10033 -> cm7mOQMVa6k -> 10033 10034 -> jCUuweEyRME -> 10034 10035 -> LDaMcOWKxjg -> 10035 10036 -> Zcrd5XzhhIk -> 10036 10037 -> j0Yg/fCjyAA -> 10037 10038 -> /LmlvRHmmmg -> 10038 10039 -> t0juuzGSKs4 -> 10039 10040 -> 9CoRCVXaak4 -> 10040 10041 -> tFmImR4j0JM -> 10041 10042 -> nI3Thy51hLg -> 10042 10043 -> mTCJh0/h2mE -> 10043 10044 -> S196xdyb3Os -> 10044 10045 -> ItOyUp+J4Q4 -> 10045 10046 -> DL87SidiOLM -> 10046 10047 -> d+Nw3xBqV44 -> 10047 10048 -> 3YzVelaC4uI -> 10048 10049 -> fAUJVOl6PaU -> 10049 

вы можете создать свою запись и обновить поле после случайного uid над функцией. функция будет проверяться на уникальность:

 CREATE FUNCTION get_unique_uid_for_your_table() RETURNS VARCHAR(255) BEGIN DECLARE chars VARCHAR(48) DEFAULT '0123456789bcdfghjklmnopqrstvwxyz'; DECLARE len INTEGER DEFAULT 8; DECLARE new_uid VARCHAR(255) DEFAULT ''; DECLARE i INTEGER DEFAULT 0; WHILE LENGTH(new_uid) = 0 OR EXISTS(SELECT uid FROM your_table WHERE uid = new_uid) DO SET len = 8; SET new_uid = ''; WHILE (len > 0) DO SET len = len - 1; SET new_uid = CONCAT(new_uid, SUBSTR(chars, FLOOR(LENGTH(chars)) * RAND(), 1)); END WHILE; END WHILE; RETURN new_uid; END // 

Для существующего материала вы можете запустить это:

 UPDATE your_table SET uid = get_unique_uid_for_your_table(); 

и в инструкции insert вы можете ввести следующее:

 INSERT INTO your_table ( #all_fields uid ) VALUES ( #all_values get_unique_uid_for_your_table() ); 

Если вы правильно поняли, вы пытаетесь разрешить пользователям выбирать свой уникальный идентификатор из таблицы, где уже не зарегистрирован пользователь. Если это так, тогда у меня будет таблица User с столбцами userID и userName. Затем верните идентификаторы пользователя, где userName все равно null.

 $query = "SELECT userID, userName FROM User WHERE userName=''"; $result=mysql_query($query); while ($row = mysql_fetch_assoc($result)) { echo $row['userID']; } 

Если вы хотите, чтобы они сами выбрали, запустите запрос с предложением where, который будет проверять, имеет ли конкретный, введенный пользователем номер, имя. Вы можете установить форму с помощью $ _POST …

 <form method="POST" action="checkID.php"> <label for="userName">User Name:</label> <input name="userName" maxlength="40" id="userName" type="text" /> <label for="userID">User ID:(int only)</label> <input name="userID" maxlength="40" id="userID" type="text" /> <input type="submit"> </form> 

и затем ваш checkID.php

 $userName = $_POST['userName']; $userID = $_POST ['userID']; 

и затем ваш запрос

 $query = "SELECT userID, userName FROM User WHERE userName='' AND userID=$userID"; $result=mysql_query($query); if ($result) { echo "number is available"; $insert = "UPDATE User SET userName=$userName WHERE userID=$userID"; $inserted=mysql_query($insert); if ($inserted) { echo "you have been inserted as: "; echo $userID; echo $userName;; } } 

Я вижу это как основы для вас. Очевидно, вам нужно будет выполнить некоторые проверки и проверки ошибок.

Надеюсь, это то, что вам нужно. Дайте мне знать, если нет, и вернемся с чем-то другим.