#sql #oracle
#sql #Oracle
Вопрос:
У меня есть столбец в таблице
таблица 1
user_id
123456
123457
123458
123459
123460
Мне нужно сгенерировать безопасные и односторонние хэшированные значения, состоящие из 12 цифр, не последовательные, без непрерывных нулей в числе. Хэшированное значение не должно перекрываться (означает уникальное) и должно быть ТОЛЬКО ЧИСЛОВЫМ. Что-то вроде:
таблица 1
user_id updated_user_id
123456 356456456345
123457 312412012412
123458 340475434545
123459 355344356461
123460 576898973434
Я в курсе ORA_HASH
, однако он выводит не более 10 цифр, а я бы хотел 12 цифр.
Есть ли способ в Oracle SQL достичь этого?
Комментарии:
1. Забудьте на мгновение о Oracle — есть ли какая-нибудь общая функция has , которая может соответствовать этим требованиям? Это кажется очень маловероятным, не в последнюю очередь потому, что они кажутся произвольными и бесполезными — в чем преимущество того, что хэш не является последовательным или не содержит повторяющихся нулей? (Некоторые из ваших выходных данных примера выполняются последовательно — первый содержит 456 дважды и 345 — или это не то, что вы имели в виду?). Если это действительно то, чего вы хотите, то вам придется разработать свой собственный алгоритм, а затем реализовать его в SQL или PL / SQL.
2. Следуя замечательным замечаниям, поднятым @alexpoole, какова ваша цель в хэшировании этих чисел? Если это для какой-либо формы безопасности, вам действительно следует хорошенько подумать о своих требованиях. Потому что они не будут обеспечивать надежное шифрование. 12 цифр — это слишком маленький пробел, чтобы гарантировать отсутствие коллизий хэшей. Использование вашего собственного алгоритма хэширования для обработки этого и других ограничений слабее, чем использование встроенных функций Oracle.
3. @APC — спасибо за ваши предложения. Я смотрю на безопасность. Каков был бы наилучший способ сделать это? Должен ли я использовать больше цифр? Каков наилучший механизм для обеспечения безопасности идентификатора пользователя?
4. @dang: что именно означает «защищенный» применительно к идентификатору? Почему
576898973434
это «более безопасно», чем 7654398? Если вам нужны некоторые случайные уникальные идентификаторы, чтобы предотвратить, например, угадывание идентификаторов, тогда используйте UUID. Но если «угадывание» действительного идентификатора является проблемой для вашего приложения, то безопасность в вашем приложении, которое контролирует доступ к информации, связанной с этим пользователем, имеет серьезные проблемы.5. Ну, как указал APC, 12 цифр в любом случае являются короткими и вообще не дают вам никакой «безопасности». Либо делайте это правильно, либо придерживайтесь имеющихся у вас идентификаторов. Вероятно, более безопасно никогда не предоставлять эти идентификаторы за пределами вашего приложения.
Ответ №1:
Я был бы осторожен при добавлении хэш-значений. Это может повлиять на коллизии. Итак:
UPDATE TABLE1
SET updated_user_id = (ORA_HASH(user_id, 1000000000, 0) - 1) * 1000
ORA_HASH(user_id, 1000, 1) - 1;
Вы должны понимать, что хэш-значения могут иметь коллизии. Таким образом, нет 100% уверенности в том, что результаты будут уникальными. Если важна гарантированная уникальность, вы можете захотеть объединить хэш с некоторыми манипуляциями с идентификатором пользователя — арифметическими или побитовыми операциями.
Комментарии:
1. Уникальность очень важна при генерации. Как я могу использовать хэш, но при этом убедиться, что он уникален?
2. @ черт . . . Вы не предоставили достаточно информации в своем вопросе, чтобы ответить на это. Это зависит от того, какова цель хэширования — означает ли это надежное шифрование или просто запутывание? Сколько существует различных идентификаторов пользователей? Меняются ли они со временем? Я бы посоветовал вам задать другой вопрос с более подробной информацией.
3. Цель — запутывание, чтобы, если кто-то взломает базу данных, он не смог идентифицировать идентификатор пользователя. У нас в системе более 100 миллионов идентификаторов пользователей, которые отправляются клиентом. Мы хотим изменить идентификаторы пользователей, чтобы они не могли сконструировать его обратно. Я задам другой вопрос с более подробной информацией.
Ответ №2:
UPDATE TABLE1
SET updated_user_id =
(
ORA_HASH(user_id, 999999999, 0) * 1000
ORA_HASH(user_id, 999999999, 1)
);
Поскольку обе хэш-функции используют разные начальные значения, 0 и 1, это должно соответствовать вашим требованиям.
Ответ №3:
Вы говорите о безопасности. Итак, давайте посмотрим, что мы можем прочитать из идентификаторов…
Допустим, мы знаем, что идентификаторы пользователей 123456 и 123460 существуют. Тогда мы можем предположить следующее:
- Также существуют идентификаторы пользователей 123457, 123458 и 123459. Однако мы не знаем, активны ли эти пользователи по-прежнему или нет.
- Пользователь 123457 был введен после пользователя 123456 и до пользователя 123458.
Я думаю, что это все. Мы извлекли все секреты, о которых нам было так ужасно любопытно.
Если это все, то вы можете применить какой-нибудь дурацкий алгоритм. Вот некоторые сгенерированные идентификаторы пользователей:
118233146610 414263244517 517233547579 618263344516 919293149578
12-значные числа. Чтобы увидеть исходные числа, посмотрите на каждую вторую цифру: 118233146610 становится 123460. Итак, чтобы сгенерировать числа, возьмите несколько случайных цифр и используйте манипулирование строками для их вставки. И в отличие от хэш-чисел, здесь не может быть дубликатов.
Комментарии:
1. Я бы погуглил Oracle random и Oracle sub string и конкатенацию Oracle и string 🙂
Ответ №4:
Добавьте 110000000000 к каждому ORA_HASH.
Комментарии:
1. ORA_HASH не гарантирует — нет непрерывных нулей.