Рандомизировать целые числа в строке - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь рандомизировать все целые числа в строке.Например, «Перенесено на счет 123456789», рандомизировано в «Перенесено на счет 256829876»

У меня уже есть медленное решение в PL / SQL, где я перебираю каждый символ в строке по отдельности.Если значение char равно 48–57 (цифры от 0 до 9), я соответственно рандомизирую цифру.

В SQL я получил это далеко:

select regexp_replace('Transferred to account 05172262116','[0-9]',
                      floor(dbms_random.value(0, 10)))
from dual;

Однако это не дает мне ожидаемого результата, так как целые числа заменяются одним уникальным значением.(Например, «Перечислено на счет 555555555») Можно ли добиться того, что я ищу, с помощью SQL?Спасибо.

Ответы [ 4 ]

0 голосов
/ 04 марта 2019

Вы можете использовать translate() с одним 10-значным случайным числом:

select translate('Transferred to account 05172262116',
  '1234567890',
  floor(dbms_random.value(1000000000, 10000000000))) from dual;

TRANSLATE('TRANSFERREDTOACCOUNT051
----------------------------------
Transferred to account 81677787668

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

with t (s) as (
  select 'Transferred to account 05172262116' from dual
  union all
  select 'Transferred to account 05172262116' from dual
)
select s, translate(s,
  '1234567890',
  floor(dbms_random.value(1000000000, 10000000000))) from t;

S                                  TRANSLATE(S,'1234567890',FLOOR(DBM
---------------------------------- ----------------------------------
Transferred to account 05172262116 Transferred to account 57238858225
Transferred to account 05172262116 Transferred to account 95587747554

Каждая цифра в исходной строке преобразуется в соответствующую цифрув случайном числе.Например, первый вывод выше был получен из сгенерированного случайного числа 6703187918. Первая цифра вашей исходной строки была 0;это десятая цифра второго аргумента для translate();таким образом, вы получите 10-ю цифру (случайной) строки замены, которая является третьим аргументом этой функции - а это 8. Вторая цифра в вашей строке - 5, которая является 5-й цифрой во втором аргументе;так что вы получите 5-ю цифру в третьем аргументе - это 7. И т. д.


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

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

0 голосов
/ 04 марта 2019

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

SELECT
    REGEXP_REPLACE('Transferred to account 05172262116', '[0-9]', '*')
FROM dual;

. Даже приведенное выше представляет некоторый риск для безопасности, поскольку показывает то же число *, что и цифры в номере счета.Но часто бывает, например, с кредитными картами или номерами счетов в данном банке, что все номера счетов в любом случае имеют одинаковую длину.

0 голосов
/ 04 марта 2019

Проблема в том, что вы делаете замену один раз.Это дает вам одно значение для замены каждого персонажа.Чтобы сделать это правильно, вам придется пройтись по каждому символу и получить новое случайное значение, чтобы заменить его.

0 голосов
/ 04 марта 2019

Если вы знаете, что числа всегда 11 цифр, вы можете явно искать это:

select regexp_replace('Transferred to account 05172262116','[0-9]{11}', floor(dbms_random.value(10000000000, 99999999999)))
from dual;

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

select regexp_replace('Transferred to account 05172262116','[0-9]+', floor(dbms_random.value(10000000000, 99999999999)))
from dual;

Как примечание: такие вещи, как номера счетов, часто удаляются с помощью translate(), но при этом получается фиксированная строка:

select translate('Transferred to account 05172262116', ' 0123456789', ' ##########')
from dual;

(И вы можете сделать то же самоевещь с regexp_replace().)

...