随机化字符串中的整数

时间:2019-03-04 14:57:28

标签: sql oracle oracle12c

我正在尝试将字符串中的所有整数随机化。 例如,“随机转入帐户123456789”随机分为“转入帐户256829876”

我在PL / SQL中已经有了一个慢速的解决方案,在该解决方案中,我逐个遍历字符串中的每个字符。如果char是48-57(数字0到9)之间的asci值,我会相应地将数字随机化。

在SQL中,我到此为止:

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

但是,由于整数被替换为单个唯一值,所以这不能给我期望的结果。 (例如“转至帐户555555555”) 通过使用SQL是否可以实现我想要的功能? 谢谢。

4 个答案:

答案 0 :(得分:1)

如果您知道数字始终为11位数字,则可以明确查找:

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

否则,您可以替换为整数,但长度可能与原始长度不同:

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()做同样的事情。)

答案 1 :(得分:1)

这个答案可能被认为是解决方案,但我认为,即使数字是随机排列的,也不应该以 any 形式显示与帐号一样敏感的信息。因此,我建议您仅使用[p>

json=[[1496832565115,13.4653],[1496835845563,13.4654]]
dic={}
lis=[]
for i in range(0,len(json)):
    dic['name'+str(i)]=json[i][0]
    dic['value'+str(i)]=json[i][1]
print(dic)

即使上述内容也存在一定的安全风险,因为它显示的SELECT REGEXP_REPLACE('Transferred to account 05172262116', '[0-9]', '*') FROM dual; 数量与帐号中的数字相同。但是,通常是这样,例如使用给定银行的信用卡或帐号,无论如何所有帐号的长度都相同。

答案 2 :(得分:0)

您遇到的问题是执行一次替换。这将为您提供一个值来替换每个字符。要正确执行此操作,您将不得不遍历每个字符并获得一个新的随机值来替换它。

答案 3 :(得分:0)

您可以将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;第二位为0。那是translate()的第二个参数的第十位;因此,您将获得(随机)替换字符串的第10个数字,该数字是该函数的第三个参数-为8。字符串中的第二个数字为5,即第二个参数的第5个数字;因此您将在第三个参数中获得第5位数字-7。依此类推。


我想这是否足够随机是有争议的,但是主要目的可能是阻止您从替换中重建原始值。您可以通过寻找新的重复值来潜在地了解原始值的形状。但是由于您可能还会在随机值中重复字符,因此不会使您走得太远。

例如,在上面的示例中,替换行具有三个连续的7位,因此您可能会认为原始行也具有三个连续的数字-但实际上没有。随机值有两个位置-第2个和第7个-都映射到新字符串中的7,您无法确定应用了哪个映射。 (因此,即使您知道随机值,在这种情况下也无法返回到原始值-当然,它不会总是有重复的数字。)