Случайность, совпадение, закономерность. Генератор случайных чисел




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

55 Comments

  1. CyberCerber

    Начали серьезно, закончили игрушками… В середине статьи затронули, как мне показалось, самый полезный момент статьи — это как быстро сформировать последовательность неповторяющихся случайных чисел. Но дальше тема никак не развилась.

    Reply
  2. Ликреонский

    (1)На мой взгляд в игре заложен глубокий смысл. Обработка помогает раскрыть для себя значение теории вероятности, сделать наблюдение. Когда на себе прочувствуешь действие теории вероятности, тогда лучше усваивается материал.

    (1)

    В середине статьи затронули, как мне показалось, самый полезный момент статьи — это как быстро сформировать последовательность неповторяющихся случайных чисел. Но дальше тема никак не развилась.

    Этому можно посветить отдельную статью. Алгоритмы на эту тему — это серьезная работа и вероятно публиковать их не захочется.

    Есть мысли продолжить тему, но уже шире, а это исследование объекта в платформе 1С.

    Reply
  3. palsergeich

    Чуть чуть не в тему, но про особенность поведения Генератора случайных чисел в 1с, может быть кому то сэкономит время при похожей ситуации:

     Для Итер = 1 По 5 Цикл
    ГСЧ = Новый ГенераторСлучайныхЧисел;
    Реквизит1 = Реквизит1+ГСЧ.СлучайноеЧисло(1,5);
    КонецЦикла;
    

     ГСЧ = Новый ГенераторСлучайныхЧисел;
    Для Итер = 1 По 5 Цикл
    Реквизит2 = Реквизит2+ГСЧ.СлучайноеЧисло(1,5);
    КонецЦикла;
    

    Причем то, что получается в случае Реквизит1 — очень бесит, когда генератор находится в отдельной функции — такая ситуация постоянна.

    Воспроизводится с древних релизов 8.2 по последний релиз 8.3

    Приходится генератор помещать как результат выполнения функции в модуль повторного использованияповторного использования на вызов.

    Объясню как наткнулся, есть связь элементов один ко многим, Ввели некую аналитику и на момент запуска надо было имеющие данные псевдо-случайно более равномерно раскидать, я без задней мысли написал функцию выдачи случайного числа, и обработал связи, сказать что я был удивлен результату — ничего не сказать, а самое обидное что при обходе кода отладкой — не воспроизводится эта ситуация, без нее — воспроизводится.

    Reply
  4. CyberCerber

    (3) Поведение в первом примере абсолютно понятно. ГСЧ без параметров инициализируется, можно сказать, текущей миллисекундной. Т.к. цикл пробежал очень быстро, время не сменилось, то каждый раз ГСЧ иниц-ся одинаковым числом. А для одинаковых начальных чисел всегда будут одинаковые последовательности.

    Reply
  5. Ликреонский

    (4)Цикл очень быстро пробежит, если только генерация идет, при выводе в диаграмму проходит немало времени между итерациями.

    В правы, кроме миллисекунд нужно перемешивать дополнительно, пропускать итерации, т.е. брать не каждое генерируемое число, а случайным образом делать выборку из последовательности.

    Например, сгенерировали 10000 чисел, но выбрать из них только 1000.

    Можно придумать еще много способов.

    Reply
  6. acsent

    Есть просто случайные числа. А есть «хорошие» случайные числа. Их используют, например, для случайного воспроизведения песен

    https://habrahabr.ru/post/343482/

    Reply
  7. Ликреонский

    (5)Хорошая почва для размышлений. При случайном выборе песни нужно не забыть воспроизвести их все, это дополнительное условие. Такое не всегда требуется.

    Reply
  8. acsent

    (7) Хорошесть там не в том чтобы все. ктож все 100 тыщ своих песен слушает за раз?

    Reply
  9. Perfolenta

    (3) вы просто не правильно им пользуетесь… генератор надо создать один раз и потом получить от него последовательность… не правильно создавать генератор для получения одного числа…

    Reply
  10. palsergeich

    (9) Если Вы внимательно прочитаете мое сообщение, то поймете причину возникновения и способ решения данной коллизии.

    Reply
  11. Perfolenta

    (10) да я только хотел сказать, что это не коллизия, а нормальное поведение генератора… даже в .Net то же самое…

    Reply
  12. Vovan1975

    интересно, каким открытием для автора будет наличие криптографически стойких генераторов ПСЕВДО случайных чисел…

    Reply
  13. cool.vlad4
    Зачем нужна случайная нумерация? Допустим мы выдаем нашим партнерам номера документов к сданному в ремонт оборудованию. Можно выдавать номера сквозной последовательной нумерации, но клиент, обладая одним номером может посмотреть как минимум соседние и зная интервал нумерации может просмотреть все документы. В приведенном примере это не ахти какой секрет, но бывает нужно сохранить в тайне информацию из других документов.

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

    Reply
  14. cool.vlad4

    (13) для озвученной задачи подойдет кодирование, либо сопоставление номера некоему генерируемому токену, который также уникален

    Reply
  15. Ликреонский

    (13)Для случайных чисел достаточно проверить уникальность сгенерированного числа (про это есть в статье), при большом количество строк, достаточно воспользоваться индексом, если поле числовое, тогда проверка будет быстрой. Так же можно воспользоваться интервалами генерирования, чтоб не проверять индекс на всем количестве строк, и сократить время проверки уникальности при очень длинных последовательностях сгенерированных данных.

    Reply
  16. Ликреонский

    (12)Никаким, я про это знаю 🙂

    Reply
  17. cool.vlad4

    (15) и зачем такие сложности?

    Reply
  18. cool.vlad4

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

    Reply
  19. cool.vlad4

    я кстати однажды делал случайные числа 1с-ом следующим образом, когда не мог использовать ВК (а ВК такая у меня есть) я заранее сгенерировал не 1С массив чисел и потом обычным 1С генератором использовал значения массива в качестве сида (опорных значений), повторений не было, хотя понятно что честным ГПСЧ это назвать сложно

    Reply
  20. Ликреонский

    (17)Токен тоже сложность. Программирование вообще непросто.

    Reply
  21. cool.vlad4

    (20) ок, я так завуалировал бредовый способ идентификации, ок?

    Reply
  22. cool.vlad4

    (20) про сложность программирования, это наверное прикол, в контексте вашей статьи

    Reply
  23. Ликреонский

    (21)Могли не вуалировать, бред в комментариях у вас хорошо получается

    Reply
  24. cool.vlad4

    (25) мои комментарии не обязательны к прочтению, у вас была возможность пройти мимо и не писать херни…понять, что, то что вы вместо идентификаторов используете хреновый алгоритм генерации случайных чисел, якобы из-за того, что кто может додуматься прибавить 1 (а случайные числа видимо генерируют такие числа, которые не являются соседними для уже сгенерированных ранее когда либо sic!) программированию вас бесполезно учить

    Reply
  25. cool.vlad4

    (25) ты на скрин блин посмотри свой — 715, 715, 716. ок, убираем твои идиотским алгоритмом повторы. внимание вопрос на миллион, 715 и 716 это соседние в твоей терминологии числа или нет?

    Reply
  26. Ликреонский

    (26)Читаем тему, исследуется объект 1С и его качества, а ваши комментарии не в тему, бред и выпендреж.

    Reply
  27. Ликреонский

    (27)Для генерации не соседних чисел применяются дополнительные алгоритмы и увеличивается разброс, а скрины демонстрируют, что для этого случая это не подходит.

    Reply
  28. cool.vlad4

    (29) ну и что дает разброс в контексте вышеописанного случая? в чем проблема клиенту перебрать числа от 1 до 1000 и получить нужное? пример про клиента бред, а не мои комментарии

    Reply
  29. cool.vlad4

    (28) ну да, все кто с тобой не согласен , это бред и выпендреж. выпендриваться ващет ты начал в комменте (20) но это было смешно в свете твоей достаточно нубской статьи

    Reply
  30. Ликреонский

    (30)

    Делаем вывод: объект ГенераторСлучайныхЧисел может генерировать повторяющиеся числа.

    Специально выделил в тексте, следующий абзац вы явно не читали, а если читали, то видимо не поняли, а теперь комментируете бред.

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

    Reply
  31. cool.vlad4

    (32) млять причем здесь генераторслучайныхчисел. ты написал, цитирую:

    Зачем нужна случайная нумерация? Допустим мы выдаем нашим партнерам номера документов к сданному в ремонт оборудованию. Можно выдавать номера сквозной последовательной нумерации, но клиент, обладая одним номером может посмотреть как минимум соседние и зная интервал нумерации может просмотреть все документы. В приведенном примере это не ахти какой секрет, но бывает нужно сохранить в тайне информацию из других документов.

    ну и какой вывод мы можем сделать? что случайная нумерация это плод твоего воображения

    Reply
  32. Ликреонский

    (33)Вывод понятен из текста и только дебил это не понимает и несет бред.

    Reply
  33. cool.vlad4

    (33) ну вот и вопрос, как твоя случайная нумерация может спасти от того, что клиент может забрутфорсить другие числа. правильный ответ — никак. но нет, мы будем до последнего отстаивать собственный бред

    Reply
  34. cool.vlad4

    (34) еше раз, как твоя уникальность или не уникальность или что еще, спасет от того , что скрипт переберет диапазон чисел от 1 до миллиарда? ну скажи честно, что ты прикидывешься особенным

    Reply
  35. Ликреонский

    (35)Повторяю, про последовательность написано, что она не подходит для целей сохранения секретности. Пример приведен неудачной генерации для этой цели.

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

    Reply
  36. cool.vlad4

    (37) как спасет увеличение интервала от брутфорса? КАК? для машины перебрать все int32 и даже long проще простого за приемлимое время, программыст. какая нахрен секретность

    Reply
  37. Ликреонский

    (36)Это особенно просто, ограничение скорости ввода чисел. Пароли тоже подбирают, однако с этим есть методы борьбы, причем широко известные. Большой, случайный номер документа в этом плане напоминает пароль, только для удобства задается исключительно знаками от 0 до 9.

    Reply
  38. Ликреонский

    (38)Кто даст перебирать все номера, сайт ограничивает скорость ввода, например 1 в секунду и тогда придется подбирать долго.

    Reply
  39. cool.vlad4

    (40) эээ, кому ты собрался ограничивать доступ, у тебя явно плохо с математикой. у тебя один клиент? почитай выше. у меня написано. за определенное время ты покроешь достаточной плотности числовое поле, чтобы программа напоролась пускай даже с твоими ограничениями (которые основываются на чем? на неверном вводе, так ведь? ) напоролась достаточно быстро на нужное число

    Reply
  40. HAMMER_59

    «Генератор случайный чисел выдает одинаковые значения, да еще последовательно.» Собственно — это один из тестов, который показывает, что человеческий мозг — плохой генератор случайных чисел. Тест в следующем: выдайте ряд случайных чисел со значениями от 1 до 6, как правило человек, помимо прочего выдает именно НЕ повторяющиеся значения, что не является правильным.

    Хотите уникальный номер, есть ведь GUID — генерируйте на здоровье, зачем велосипед изобретать?

    Reply
  41. Ликреонский

    (31)В комменте (20) больная самооценка нашла выпендреж.

    Вы предложили, то что к статье не относится, полный оффтоп.

    Давайте предлагать клиентам код в виде 93247skdYUkslkcn838792, для проверки статуса рекламации. Я думаю он просто позвонит по телефону и спросит: «Ну, как там мое оборудование, уже отремонтировали?»

    Reply
  42. cool.vlad4

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

    Reply
  43. cool.vlad4

    (43) а давайте будем предлагать числа с большим интервалом, ага . 14153639478675186324759348759384756398 подойдет, да?

    Reply
  44. cool.vlad4

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

    Reply
  45. Ликреонский

    (41)Во первых можно применять последовательность из 20 цифр, а не int32.

    Во вторых, если на сервере будет активность по подбору чисел с миллиона адресов, то он просто ляжет или заблокируется от DDoS атаки.

    Если секретность высокая, например коды из предоплаченных карт, но ничего не мешает к числам добавлять дополнительные символы или сильно увеличить разрядность.

    Числа удобнее тем, то не возникает разночтений между «С» и «C».

    По комбинаторике, если мы увеличиваем количество возможных символов, то увеличиваем основание для вариантов, а если увеличиваем разрядность то увеличиваем степень. Например:

    Буквы английского алфавита и цифры, в основании получаем 36 и разрядов предполагаем 10 (36#k8SjZc9Dxk10 = 3,6561584 × 10#k8SjZc9Dxk15), или только числа, в основании и 20 разрядов (10#k8SjZc9Dxk20). Второй вариант дает большее число.

    Reply
  46. Ликреонский

    (45)По крайней мере нет разночтений в буквах.

    Reply
  47. Ликреонский

    (46)Незачем создавать доступ для получения одного документа

    Reply
  48. Ликреонский

    (42)Согласен, чаще всего для машинной обработки именно так и нужно делать, но человека GUID пугает.

    Reply
  49. Ликреонский

    (44)Совет учи появляется когда кончаются аргументы, это не относится к спору. Я надеюсь что мы эмоции выплеснули и можем говорить конструктивно, поэтому предлагаю ограничится формулами и здравым смыслом,

    Reply
  50. Ликреонский

    Ийон Тихий

    Предлагаю наше обсуждение перенести в одну ветку, сюда, и конструктивно предоставить наши аргументы

    Reply
  51. Ликреонский

    (52)Задача:

    Клиенту некой организации выдать документ рекламации и дать уникальное число для отслеживания его статуса на сайте.

    Или другой вариант, но чтоб по телефону не отвлекал людей от работы, и мог как можно раньше забрать свое оборудование из ремонта.

    Ваше предложение.

    Reply
  52. rpgshnik

    (2) Какой смысл? Я пришел в 1С из Delphi. Там было всё просто — Randomize(N).

    Зачем искать смысл в простых вещах, которые должны работать, а что бы генератор 1С заработал нужно приложить кодинг, бред. Юзаю данную функцию и не парюсь http://forum.infostart.ru/forum9/topic27839/message309401/#message309401 и кстати там очень много вариантов разных.

    А если мне нужна последовательность от 1 до 100 без повторений и хаотичная, то мы просто создаем таблицу, первая колонка п/п, вторая генерация с помощью выше приведенной мной функции числа от 1 до 1000 допустим и потом сортируем по сгенерированному столбцу таблицу, вуаля последовательность без повторений и случайная (собственно у вас это то же сделано в примере…)

    Reply
  53. Ликреонский

    (54)

    Там было всё просто — Randomize(N)

    Я тоже пользовался такой функцией, но там приходилось предпринимать дополнительные действия, чтобы привести к нужному интервалу значений чисел. Пережить можно, но в ГенераторСлучайныхЧисел этим и соблазнительнее, поэтому раскрываю особенности его работы.

    Reply
  54. palsergeich

    (53) не самое быстрое решение, но дающее уникальность:

    Воспользуйтесь автонумератором специально для этого заведенного мусорного справочника. Я видел системы, которые так делают и нормально работают при больших нагрузках. Один минус — монотонное возрастание.

    Reply
  55. user916475

    очень познавательно, никогда об этом не задумывалась даже

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *