Vertica 中 Id_number 上的随机数字数据屏蔽
Random Digit Data Masking on Id_number in Vertica
我需要在第 6 位和第 12 位之间随机屏蔽 id_number 的 4 位数字。
示例:
555444888777 --> 55544x8x8xx7
我写了下面的代码,但它是每 2 位随机的。在 Vertica 中,给定 间隔 和 需要多少位数来屏蔽 是否有任何随机屏蔽的解决方案?
SELECT OVERLAYB(OVERLAYB(OVERLAYB(OVERLAYB('555444888777', 'x', 5+RANDOMINT(2)),'x', 7+RANDOMINT(2)),'x', 9+RANDOMINT(2)),'x',11+RANDOMINT(2));
这有点疯狂,但似乎有效:
with my_range as (
select 6 as n
union all select 7 as n
union all select 8 as n
union all select 9 as n
union all select 10 as n
union all select 11 as n
union all select 12 as n),
random_positions as (
select n
from my_range
order by random()
limit 4),
quartiles as (
select n,
ntile(4) over(order by n) as quartile
from random_positions),
sorted_positions as (
select max(case when quartile = 1 then n end) as random1,
max(case when quartile = 2 then n end) as random2,
max(case when quartile = 3 then n end) as random3,
max(case when quartile = 4 then n end) as random4
from quartiles)
select '555444888777' as string_original,
overlay(
overlay(
overlay(
overlay('555444888777' placing 'x' from random1)
placing 'x' from random2)
placing 'x' from random3)
placing 'x' from random4)
as string_masked
from sorted_positions;
执行示例:
$ vsql -f tmp.sql
string_original | string_masked
-----------------+---------------
555444888777 | 55544xx8xx77
(1 row)
$ vsql -f tmp.sql
string_original | string_masked
-----------------+---------------
555444888777 | 55544xx8x7x7
(1 row)
$ vsql -f tmp.sql
string_original | string_masked
-----------------+---------------
555444888777 | 55544x8x8x7x
(1 row)
解释:
my_range
用 6 到 12 的数字构建一个记录集
random_positions
随机排序记录集,只返回 4 个位置
quartiles
将四分位数分配给每个随机位置,因此 sorted_positions
可以将结果转换为单个记录
- 最后,最后一个
select
在四个随机位置应用了四次 OVERLAY function
如果你真的想用 'x' 随机替换一个数字,随机地,位置 5、7、9 和 11 之后的第一个或第二个数字,就像你编码的那样,然后创建一个函数作为我做到了,所以您不需要每次都对嵌套的 OVERLAYB() 调用重新编码。
如果您想要更多差异,也可以用 RANDOMINT() 调用替换 5、7、9 和 11。
但是,如果您想改变替换次数(从 4 次到其他次数),您将不得不为不同的替换次数重新编写函数。或者经历在 C++、Java、R 或 Python.
中编写 UDx(用户定义的扩展)的麻烦
检查 Vertica 文档;从这里开始:
https://www.vertica.com/docs/10.0.x/HTML/Content/Authoring/SQLReferenceManual/Statements/CREATEFUNCTIONUDF.htm?zoom_highlight=create%20function
话虽如此,这里是具有相同功能的函数及其测试:
CREATE OR REPLACE FUNCTION maskrand(
s VARCHAR(256)
)
RETURN VARCHAR(256)
AS
BEGIN
RETURN (
OVERLAYB(
OVERLAYB(
OVERLAYB(
OVERLAYB(
s
, 'x'
, 5+RANDOMINT(2)
)
,'x'
, 7+RANDOMINT(2)
)
,'x'
, 9+RANDOMINT(2)
)
,'x'
, 11+RANDOMINT(2)
)
);
END;
-- test ...
WITH indata(s) AS (
SELECT '555444888777'
UNION ALL SELECT '666333444888'
)
SELECT
s, maskrand(s) AS masked
FROM indata;
-- out s | masked
-- out --------------+--------------
-- out 555444888777 | 5554x48x8xx7
-- out 666333444888 | 6663x3x4x88x
我需要在第 6 位和第 12 位之间随机屏蔽 id_number 的 4 位数字。
示例: 555444888777 --> 55544x8x8xx7
我写了下面的代码,但它是每 2 位随机的。在 Vertica 中,给定 间隔 和 需要多少位数来屏蔽 是否有任何随机屏蔽的解决方案?
SELECT OVERLAYB(OVERLAYB(OVERLAYB(OVERLAYB('555444888777', 'x', 5+RANDOMINT(2)),'x', 7+RANDOMINT(2)),'x', 9+RANDOMINT(2)),'x',11+RANDOMINT(2));
这有点疯狂,但似乎有效:
with my_range as (
select 6 as n
union all select 7 as n
union all select 8 as n
union all select 9 as n
union all select 10 as n
union all select 11 as n
union all select 12 as n),
random_positions as (
select n
from my_range
order by random()
limit 4),
quartiles as (
select n,
ntile(4) over(order by n) as quartile
from random_positions),
sorted_positions as (
select max(case when quartile = 1 then n end) as random1,
max(case when quartile = 2 then n end) as random2,
max(case when quartile = 3 then n end) as random3,
max(case when quartile = 4 then n end) as random4
from quartiles)
select '555444888777' as string_original,
overlay(
overlay(
overlay(
overlay('555444888777' placing 'x' from random1)
placing 'x' from random2)
placing 'x' from random3)
placing 'x' from random4)
as string_masked
from sorted_positions;
执行示例:
$ vsql -f tmp.sql
string_original | string_masked
-----------------+---------------
555444888777 | 55544xx8xx77
(1 row)
$ vsql -f tmp.sql
string_original | string_masked
-----------------+---------------
555444888777 | 55544xx8x7x7
(1 row)
$ vsql -f tmp.sql
string_original | string_masked
-----------------+---------------
555444888777 | 55544x8x8x7x
(1 row)
解释:
my_range
用 6 到 12 的数字构建一个记录集random_positions
随机排序记录集,只返回 4 个位置quartiles
将四分位数分配给每个随机位置,因此sorted_positions
可以将结果转换为单个记录- 最后,最后一个
select
在四个随机位置应用了四次 OVERLAY function
如果你真的想用 'x' 随机替换一个数字,随机地,位置 5、7、9 和 11 之后的第一个或第二个数字,就像你编码的那样,然后创建一个函数作为我做到了,所以您不需要每次都对嵌套的 OVERLAYB() 调用重新编码。
如果您想要更多差异,也可以用 RANDOMINT() 调用替换 5、7、9 和 11。
但是,如果您想改变替换次数(从 4 次到其他次数),您将不得不为不同的替换次数重新编写函数。或者经历在 C++、Java、R 或 Python.
中编写 UDx(用户定义的扩展)的麻烦检查 Vertica 文档;从这里开始: https://www.vertica.com/docs/10.0.x/HTML/Content/Authoring/SQLReferenceManual/Statements/CREATEFUNCTIONUDF.htm?zoom_highlight=create%20function
话虽如此,这里是具有相同功能的函数及其测试:
CREATE OR REPLACE FUNCTION maskrand(
s VARCHAR(256)
)
RETURN VARCHAR(256)
AS
BEGIN
RETURN (
OVERLAYB(
OVERLAYB(
OVERLAYB(
OVERLAYB(
s
, 'x'
, 5+RANDOMINT(2)
)
,'x'
, 7+RANDOMINT(2)
)
,'x'
, 9+RANDOMINT(2)
)
,'x'
, 11+RANDOMINT(2)
)
);
END;
-- test ...
WITH indata(s) AS (
SELECT '555444888777'
UNION ALL SELECT '666333444888'
)
SELECT
s, maskrand(s) AS masked
FROM indata;
-- out s | masked
-- out --------------+--------------
-- out 555444888777 | 5554x48x8xx7
-- out 666333444888 | 6663x3x4x88x