За последние 24 часа нас посетили 18338 программистов и 1634 робота. Сейчас ищут 1637 программистов ...

Алгоритмы генерации уникальных кодов по формату - идеи.

Тема в разделе "Решения, алгоритмы", создана пользователем Psih, 11 авг 2010.

  1. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Столкнулся тут с задачей генерации уникальных кодов для ваучеров, в больших объёмах.
    Код статичной длинны и желательно что бы он генерировался достаточно быстро, по возможности что бы не нужно было в цикле проверять по базе есть такой код или нет (кол-во записей быстро расти будет, по 10к в месяц как минимум).

    Пока вот не придумал как это сделать.
     
  2. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
  3. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Правда, там есть нюанс в его алгоритме... ссылка на хабр вроде в статье есть, а там коменты смотри.
     
  4. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    GUID И будет тебе счастье... мы сейчас их активно пользуем
     
  5. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Виндовый GUID вроде как не обеспечивает непредсказуемость.
     
  6. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    440Hz
    Мне вот надо 11 знаковый код для ваучеров :) Обрезать UUID, GUID'ы как-то не алё, повторятся будут :(
     
  7. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    GUID суров, даже при базе 36 "всего" 25 символов. Для ваучеров не годится - слишком длинное.
     
  8. antonn

    antonn Активный пользователь

    С нами с:
    10 июн 2007
    Сообщения:
    2.996
    Симпатии:
    0
    По сути неозвученных требований - инкремент.
    Что тут гадать - ума не приложу. Ну только если для понта сразу нужны кучерявые номера с кучей разных циферок и буковок. А так - накопятся.
     
  9. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Ну дело в том, что я делаю щас продажу skype ваучеров и соответственно их пополнение. По этому простой инкремент не годится ну никак, код ваучера должен быть случайным и по возможности не повторятся при генерации, что бы не приходилось делать:

    1. 1. Сгенерировали код
      2. Сделали запрос на базу
      3. Если такой ваучер уже есть, идём в пункт 1.
      4. Добавляем ваучер в базу данных и отсылаем клиенту код

    Судя по всему пока склоняется к такому решению:
    PHP:
    1. <?php
    2. echo base_convert(uniqid(), 16, 36).'<br />'; // 10 symbol code
    3. echo base_convert(uniqid('', true), 16, 36).'<br />'; // 17 symbol code
    4.  
    В принципе наверно 17 символов даже сойдет :)
     
  10. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    Psih
    PHP:
    1. echo base_convert(uniqid('', true), 16, 36).'<br />'; // 17 symbol code
    это зависит от метки времени, юзай md5(microtime(1));

    просто в одну секунду uniqid могут совпасть, нарывался :(
     
  11. Апельсин

    Апельсин Активный пользователь

    С нами с:
    20 мар 2010
    Сообщения:
    3.645
    Симпатии:
    2
    Psih
    А че если не генерить код при запросе, а иметь базу уже готовых и уникальных. Не безопасно конеш, но быстрооООоо))
    И когда нуна отослать код - просто выбирается строка, выдается ее код, затем она же удаляется. И такой список постепенно "пополнять" новыми записями по мере необходимости.
     
  12. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    неверю
     
  13. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    проверь.
     
  14. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    всё ещё не верю
     
  15. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    Mr.M.I.T.
    и правда неполучается повторить, возможно какая то бага с делителем времени в старых версиях пхп или тп, но зависит от времени или подобной вещи - 100%.

    Код (Text):
    1. 4c62f0e8792cc
    2. 4c62f0e879e7c
    3. 4c62f0e87b622
    4. 4c62f0e87c1cc
    5. 4c62f0e87cd90
    6. 4c62f0e87d954
    7. 4c62f0e87e517
    8. 4c62f0e87f0dc
    9. 4c62f0e87fca0
    10. 4c62f0e880864
    11. 4c62f0e881429
    12. 4c62f0e881ffe
    13. 4c62f0e882bc5
    14. 4c62f0e883869
    15. 4c62f0e88433c
    16. 4c62f0e884f00
    17. 4c62f0e885ac2
    18. 4c62f0e886686
    19. 4c62f0e88724a
    20. 4c62f0e887e0f

    Код (Text):
    1. for($i = 0; $i < 20; $i++)
    2. {
    3.   echo uniqid()."\n";
    4. }
     
  16. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    для хаотичности большей я все равно юзаю мд5 :)
     
  17. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    дуд уже не тот...
     
  18. Апельсин

    Апельсин Активный пользователь

    С нами с:
    20 мар 2010
    Сообщения:
    3.645
    Симпатии:
    2
    ахаха))
     
  19. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    видимо и прада могут.
    Код (Text):
    1. /*
    2.    +----------------------------------------------------------------------+
    3.    | PHP Version 5                                                        |
    4.    +----------------------------------------------------------------------+
    5.    | Copyright (c) 1997-2010 The PHP Group                                |
    6.    +----------------------------------------------------------------------+
    7.    | This source file is subject to version 3.01 of the PHP license,      |
    8.    | that is bundled with this package in the file LICENSE, and is        |
    9.    | available through the world-wide-web at the following url:           |
    10.    | http://www.php.net/license/3_01.txt                                  |
    11.    | If you did not receive a copy of the PHP license and are unable to   |
    12.    | obtain it through the world-wide-web, please send a note to          |
    13.    | license@php.net so we can mail you a copy immediately.               |
    14.    +----------------------------------------------------------------------+
    15.    | Author: Stig Sжther Bakken <ssb@php.net>                             |
    16.    +----------------------------------------------------------------------+
    17.  */
    18.  
    19. /* $Id: uniqid.c 293036 2010-01-03 09:23:27Z sebastian $ */
    20.  
    21. #include "php.h"
    22.  
    23. #include <stdlib.h>
    24. #if HAVE_UNISTD_H
    25. #include <unistd.h>
    26. #endif
    27.  
    28. #include <string.h>
    29. #include <errno.h>
    30.  
    31. #include <stdio.h>
    32. #ifdef PHP_WIN32
    33. #include "win32/time.h"
    34. #else
    35. #include <sys/time.h>
    36. #endif
    37.  
    38. #include "php_lcg.h"
    39. #include "uniqid.h"
    40.  
    41. /* {{{ proto string uniqid([string prefix [, bool more_entropy]])
    42.    Generates a unique ID */
    43. #ifdef HAVE_GETTIMEOFDAY
    44. PHP_FUNCTION(uniqid)
    45. {
    46.     char *prefix = "";
    47. #if defined(__CYGWIN__)
    48.     zend_bool more_entropy = 1;
    49. #else
    50.     zend_bool more_entropy = 0;
    51. #endif
    52.     char *uniqid;
    53.     int sec, usec, prefix_len = 0;
    54.     struct timeval tv;
    55.  
    56.     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &prefix, &prefix_len,
    57.                               &more_entropy)) {
    58.         return;
    59.     }
    60.  
    61. #if HAVE_USLEEP && !defined(PHP_WIN32)
    62.     if (!more_entropy) {
    63. #if defined(__CYGWIN__)
    64.         php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must use 'more entropy' under CYGWIN");
    65.         RETURN_FALSE;
    66. #else
    67.         usleep(1);
    68. #endif
    69.     }
    70. #endif
    71.     gettimeofday((struct timeval *) &tv, (struct timezone *) NULL);
    72.     sec = (int) tv.tv_sec;
    73.     usec = (int) (tv.tv_usec % 0x100000);
    74.  
    75.     /* The max value usec can have is 0xF423F, so we use only five hex
    76.      * digits for usecs.
    77.      */
    78.     if (more_entropy) {
    79.         spprintf(&uniqid, 0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg(TSRMLS_C) * 10);
    80.     } else {
    81.         spprintf(&uniqid, 0, "%s%08x%05x", prefix, sec, usec);
    82.     }
    83.  
    84.     RETURN_STRING(uniqid, 0);
    85. }
    86. #endif
    87. /* }}} */
    88.  
    89. /*
    90.  * Local variables:
    91.  * tab-width: 4
    92.  * c-basic-offset: 4
    93.  * End:
    94.  * vim600: sw=4 ts=4 fdm=marker
    95.  * vim<600: sw=4 ts=4
    96.  */
     
  20. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    не пизди книжный червь :D
     
  21. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    а то, я грю же СТАЛКИВАЛСЯ, а не читал в книжке от фабиена это :)
     
  22. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    в таком варианте
    uniqid('', true)
    вероятность невероятная

    тем более всегда можно доработать исходник =)
     
  23. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Виртуальная реальность или реальная виртуальность. Мы до конца ещё не определились.
     
  24. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    ага, так уже сложнее)) ну это так, для "чтобы знали" я сказал, и то засрать попытались сразу)) фу на вас, обижусь, я уже не тот, пошел на покой лучше :)
     
  25. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    иди давай пей квас вкусный)