gifts2017

Генератор случайных чисел/символов

Опубликовал Oleg Kabysh (okabysh) в раздел Программирование - Практика программирования

Для 1С:Предприятие 8.2.17(и выше) или 8.3

В данном примере показано, как можно сгенерировать строку длинной в 6-ть символов, состоящие из цифр, маленьких и больших букв латиницы.

Процедура КнопкаСгенерировать()    
    Для Сч = 1 по 100 Цикл
        Сообщить(ГенерацияСлучайногоСимвола(ТекущаяУниверсальнаяДатаВМиллисекундах()));
    КонецЦикла;   
КонецПроцедуры

Функция ГенерацияСлучайногоСимвола(Счетчик)
    ГСЧ = Новый ГенераторСлучайныхЧисел(Счетчик);    
    СлучайнаяСтрока = "";
    // генерируем случайное число из 6-ти символов, например "d0c8Yf"
    Для Сч = 1 по 6 Цикл        
        Набор = ГСЧ.СлучайноеЧисло(1,3);    
        Если Набор = 1 Тогда
            // это число
            СлучайныйСимвол = ГСЧ.СлучайноеЧисло(0,9);    
        ИначеЕсли Набор = 2 Тогда
            // это Большая буква латиницы
            СлучайныйСимвол = Символ(ГСЧ.СлучайноеЧисло(65,90));
        ИначеЕсли Набор = 3 Тогда
            // это маленькая буква латиницы
            СлучайныйСимвол = Символ(ГСЧ.СлучайноеЧисло(97,122));
        КонецЕсли;
        СлучайнаяСтрока = СлучайнаяСтрока + СлучайныйСимвол;
    КонецЦикла;      
    Возврат(СлучайнаяСтрока);    
КонецФункции

!Особенность.Если ТекущаяУниверсальнаяДатаВМиллисекундах() вернет 2 и более одинаковых числа (т.е. сервер настолько быстрый, что 2 и более операции произошли в рамках 1 миллисекунды), будут сгенерированы 2 и более одинаковых "случайных числа".

Для меня уникальность значений очень критична, поэтому я сохраняю все сгенерированные случайные числа в регистр сведений и после генерирования нового случайного числа проверяю его на наличие в регистре сведений  (естественно, 99,9999% его там нет). Но если вдруг произойдет совпадение, генерирую новое случайное число и снова проверяю на наличие в регистре.

Скачать файлы

Наименование Файл Версия Размер
RandomNumberGenerator
.epf 6,34Kb
07.10.16
0
.epf 6,34Kb Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Pavel Fomin (Pasha1st) 28.10.16 08:05
Почему-то многие забывают о такой вещи, что если строка предназначена для человека (это генератор паролей, например), то не стоит допускать одновременного появления в пароле визуально схожих символов - 0 и O, 1, l и I. Их требуется или полностью исключить, или оставить только какой-то однозначный вариант, например только цифры. А ещё можно сделать управление вероятностью появления символа из конкретного набора (больше-меньше цифр).
okabysh; dj_serega; +2 Ответить 1
2. Oleg Kabysh (okabysh) 29.10.16 20:05
(1) Pasha1st,
Приветствую, Павел.
Спасибо за комментарий.
Если использовать для генерации паролей пользователю, тогда очень желательно убрать генерацию символов, которые могут быть похожи друг на друга. Я обновлю данную обработку с Вашим пожеланием, вдруг и мне позже пригодится.
Лично я использовал для добавления данного идентификатора в назначение платежа. Не буду вдаваться в подробности, но эти символы обрабатывает компьютер как с одной так и с другой стороны, поэтому компьютер точно поймет какой символ пришел к нему)
3. Александр Полетаев (Alias) 31.10.16 10:11
(2) "Для меня уникальность значений очень критична, поэтому я сохраняю все сгенерированные случайные числа в регистр сведений"
А если не секрет, почему именно такой, не самый оптимальный с моей точки зрения, путь выбран? Это же хранить все выданные последовательности, да ещё и постоянно проверять уникальность...
Скажите, разве не проще было сделать самый обычный инкрементальный счётчик, хоть в той же константе? Никаких регистров, никаких проверок... Сплошные плюсы! Знай себе +1 делай и всё.
А если очень хочется иметь именно 6-тисимвольный код, можно преобразовать значение полученного счётчика в символьную последовательность, -- алгоритм абсолютно аналогичен переводу в другую систему счисления. Бонусом имеем ещё и отслеживаемую хронологию...
М-м?
4. Oleg Kabysh (okabysh) 02.11.16 01:15
(3) Александр, спасибо за комментарий.
ответ на: "А если не секрет, почему именно такой, не самый оптимальный с моей точки зрения, путь выбран? Это же хранить все выданные последовательности, да ещё и постоянно проверять уникальность...".
Дело в том, что мне нужно знать, какому объекту я выдал в моем случае 6-ти значный код, поэтому я храню данные в регистре по 2-м измерениям: ссылку на объект и 6-ти значный код с типом "Строка". Когда потребуется найти объект, я его всегда найду, зная 6ть символов кода. В моем случае требовалось использовать минимум символов для кодирования, но чтобы их было нельзя подобрать, поэтому я не мог брать простой счетчик, к примеру, от 100000 + 1, +1, +1 ...
Еще можно использовать GUID, тогда уникальность практически на 100% гарантируется, но коду требуется уже 36 символов. Повторюсь, в моей ситуации 36 символов это много и следовательно не подходит. Поэтому я сделал, как сделал)

Основная цель публикации:
показать на "пальцах" как использовать ГенераторСлучайныхЧисел() и его особенность.
Так что пусть каждый реализует свою логику как считает нужным.
5. Александр Полетаев (Alias) 02.11.16 09:58
(4) okabysh, Ясно, спасибо за уточнение. "...Чтобы их было нельзя подобрать..." -- это ключевая фраза. Да, в таком случае автоинкрементируемый счётчик не очень подходит -- он слишком легко прогнозируем (что в других случаях могло бы быть плюсом).
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа