【问题标题】:Random Digit Data Masking on Id_number in VerticaVertica 中 Id_number 上的随机数字数据屏蔽
【发布时间】:2020-12-18 05:36:12
【问题描述】:

我需要在第 6 位和第 12 位之间随机屏蔽 id_number 的 4 位数字。

示例: 555444888777 --> 55544x8x8xx7

我编写了以下代码,但每 2 位数字都是 rondom。是否有任何解决方案可以在 Vertica 中使用给定的 intervals需要掩码的位数 进行 rondomly 掩码?

SELECT OVERLAYB(OVERLAYB(OVERLAYB(OVERLAYB('555444888777', 'x', 5+RANDOMINT(2)),'x', 7+RANDOMINT(2)),'x', 9+RANDOMINT(2)),'x',11+RANDOMINT(2));

【问题讨论】:

    标签: sql vertica data-masking


    【解决方案1】:

    如果你真的想在 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
    

    【讨论】:

      【解决方案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 四次

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-27
        • 2013-11-16
        • 1970-01-01
        相关资源
        最近更新 更多