22.11.2014

Мускул и Йожег

Ну вот, по роду своей деятельности пришлось столкнуться вот с этими зверьками. Надо сказать, что они мне понравились.
MySQL существенно улучшился за последние несколько лет. Позволяет, по сравнению с Interbase, делать очень интересные запросы. И работает ничего так себе, быстро достаточно. Ну, конечно, есть пара нюансов, которые удивляют. Так вот, я о них :)

Первое, это конкатенация слов. Вроде бы есть стандарт SQL, но по умолчанию используется другой механизм. А отказ от стандарта -  ради "насильников". :) Поэтому приходится использовать функцию для соединения строк, вместо оператора. Хотя оператор, предлагаемый стандартом SQL, тоже несколько странный.

Вторая особенность - это логические операции. Сразу видно, что в Мускул они пришла из мира "насильников". Возможно, даже "гнусных". :)
Идея в том, что значение любого типа может трактоваться как логическое, а логическое, на самом деле, это целое. 0 означает "ложь", а все остальное - "истину". Стандартно логические условия в качестве истины возвращают единицу.
В результате можно мутить вот такие вот выражения:

salary*tax*(salary>1000).

Здесь мы рассчитываем налог на зарплату, при условии, что она больше 1000. Если меньше 1000, то налог равен нулю. В соответствии с требованиями стандарта такое выражение пришлось бы писать по-другому. Например, так:

case when salary > 1000 then salary*tax else 0 end

Конечно, первый подход гораздо эффективней и компактней. Но! Как легко же сделать ошибку. В частности, я наткнулся один раз. Начал писать условия в разделе where, отвлекся на что-то и получилось что-то вроде

where stype=1 and mode

После mode подразумевалось дописать условие. Но так как я отвлекся, то, вернувшись к задаче, дописать забыл. И в Мускуле это не ошибка, а вполне легальная запись логического выражения, так как любое значение может трактоваться как логическое. Так что будьте осторожны. Правильное условия выглядело примерно так:

where stype=1 and mode=4

Йожег тоже поразил. Включенной по умолчанию настройкой, которая перед сохранением редактируемого строкового поля в "гриде" пытается его сначала выполнить. Типа, а вдруг там какое-то SQL выражение. И если там вдруг правда оказалось SQL-выражение, то в поле будет записан результат его вычисления.
Это сделано для того, что бы пользователь мог что-то выполнить. Честное слово, руки бы отрывал. :)
Но есть нюасн: вычисляются многие выражения, но не CASE. Не понятно, что за прикол, то ли ошибка, то ли фича такая.
В общем, тоже словил косяк на пустом месте. Потому как не ожидал такой гадости от порядочной программы. Хотя меня предупреждали о такой вот занимательной особенности Йожега.

02.11.2014

Строковый хэш

Наконец-то появилось немножко свободное время. Поэтому решил развлечься. Потренироваться в программировании.
Люблю писать маленькие, совершенно бесполезные и никому не нужные программки. Вот и сейчас, в продолжении предыдущего поста, решил продемонстрировать сам себе, как оно может работать. Естественно, в код обязательно для пущего самоудовлетворения вставляются ассемблерные вставки.
В общем, в формочку надо ввести предложение данные, только на русском языке. Потому что такой дебильный вариант закона о персональных данных только у нас. :) Все приводится к верхнему регистру.
После чего формируется строка, из которой удаляются шумовые символы (пробелы и точки, другие шумовые символы ввести нельзя). Далее это строка по простейшему алгоритму перемешивается. Перемешивание зависит только от самой строки.
После этого происходит расчет хэш-суммы в виде 32-разрядного целого по простейшей схеме, примерно такой:
Sum := Sum*S[i]+S[i].
Недостаток такого подхода состоит в том, что при сколько-нибудь значительно длине строки происходит переполнение 32-разрядного целого, и, таким образом, в формировании хэша участвует только несколько последних символов строки. А начало строки "забывается" алгоритмом.
Что бы избежать этого, старшая часть 64 числа после умножения регулярно складывается с младшей.
Ну и можно указать начальное значение для переменной Sum (поле "Смещение"), это аналог "соли" во избежание быстрого подбора хэша по словарю.
Ну и конечно, в вырожденном случае, когда длина всех символьных полей оказывается мала (то есть все текстовые поля состоят из одной буквы), хэш функция вырождается. Но, я думаю, такое маловероятно с учетом особенностей русского языка. :)
Если что, алгоритм работает с ANSI кодировкой, в принципе, никто не мешал мне использовать UNICODE, но заморачиваться не охота.
Впервые попробовал делать 64-разрядные вставки на ассемблере. Это классно! Дополнительные регистры и 64-разрядные арифметические операции существенно сокращают и упрощают код. Я бы вообще Intel'овскую архитектуру запретил законодательно. :) да здравствует RISC!
Да, программка здесь, если кому в голову придет безумная идея ее запустить.

15.09.2014

ЗоПД, обезличивание и аутентификация

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

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

Трудности тут связаны с тем, что обезличивать данные очень не удобно, и, чаще всего, невозможно. Что значит обезличить данные? Это значит убрать из персональных данных все сведения, по которым можно установить личность человека, к которым эти данные относятся. То есть сюда сразу автоматически попадают фамилия, имя и отчество, а также все федеральные идентификаторы (номер паспорта, СНИЛС и ИНН). Естественно, чаще всего из базы трудно убрать как минимум ФИО по тем или иным причинам, а также идентификаторы. Это может быть связано как с особенностью работы организации, так и с тем, что эти сведения по закону требуется передавать в гос. органы.
Но все же иногда бывают ситуации, когда идентифицирующие человека признаки могут быть удалены из некоторых баз, которые используются для организации производственных процессов. В этом случае ФИО и прочие атрибуты заменяются каким-то внутренним идентификатором. Например, это может быть табельный номер сотрудника или номер студенческого билета. В случае отсутствия подобных атрибутов могут использоваться автоматически генерируемые номера, которые выдаются клиентам программной системы.
И если с автоматической аутентификацией клиента при удаленном использовании системы особых проблем не возникают, все методы такой аутентификации известны и хорошо разобраны, то в случае, когда требуется ручная аутентификации субъекта ситуация не так радужна.
Ручная аутентификация может потребоваться в том случае, когда удаленный доступ к системе не предусмотрен или не возможен.

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

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

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

Также такое значение хэш-функции может использоваться и для поиска связанной с субъектом информации по его идентифицирующей персональной информации. В этом случае на рабочем месте оператора вводится необходимая информация, хэшируется и полученное значение отправляется на сервер для поиска. Таким образом, идентифицирующая персональная информация не передается по сети, что позволяет практически отказаться от дополнительных мер защиты, навязываемых подзаконными актами к ЗоПД.
В принципе, так как по значению хэш-функции в данном ее применении не возможно предпринять каких-либо деструктивных действий, то особых требований к ее криптостойкости нет. Поэтому можно использовать как стандартные алгоритмы, такие как MD5, SHA-2 или ГОСТовской вариант. Недостаток таких функции состоит в их достаточно высокой вычислительной сложности, что не всегда удобно. Поэтому можно использовать и свои, более простые варианты хэш-функций.

С точки зрения ЗоПД использование значения функции свертки вполне легально, так как там не определены способы получения идентификатора для обезличивания данных.