### 6.5.5 MySQL企业数据屏蔽和去标识化功能说明

MySQL Enterprise Data Masking and De-Identification 插件库包括几个功能，可以分为以下几类：

-   [数据屏蔽功能](data-masking-functions.html#data-masking-masking-functions)

-   [随机数据生成函数](data-masking-functions.html#data-masking-generation-functions)

-   [基于随机数据字典的函数](data-masking-functions.html#data-masking-dictionary-functions)

    从 MySQL 8.0.19 开始，这些函数支持单字节`拉丁语1`字符串参数和返回值的字符集。在 MySQL 8.0.19 之前，函数将字符串参数视为二进制字符串（这意味着它们不区分字母大小写），字符串返回值是二进制字符串。可以看到返回值字符集的区别如下：

    MySQL 8.0.19 及更高版本：


```
mysql> SELECT CHARSET(gen_rnd_email());
+--------------------------+
| CHARSET(gen_rnd_email()) |
+--------------------------+
| latin1                   |
+--------------------------+
```

在 MySQL 8.0.19 之前：

```
mysql> SELECT CHARSET(gen_rnd_email());
+--------------------------+
| CHARSET(gen_rnd_email()) |
+--------------------------+
| binary                   |
+--------------------------+
```

对于任何版本，如果字符串返回值应该在不同的字符集中，则将其转换。下面的例子展示了如何转换结果[`gen_rnd_email()`](data-masking-functions.html#function_gen-rnd-email)到`utf8mb4`字符集：

```
SET @email = CONVERT(gen_rnd_email() USING utf8mb4);
```

要显式生成二进制字符串（例如，生成类似于 8.0.19 之前的 MySQL 版本的结果），请执行以下操作：

```
SET @email = CONVERT(gen_rnd_email() USING binary);
```

可能还需要转换字符串参数，如[使用屏蔽数据进行客户识别](data-masking-usage.html#data-masking-usage-customer-identification).

如果从内部调用 MySQL Enterprise Data Masking and De-Identification 函数[**mysql**](mysql.html)客户端，二进制字符串结果使用十六进制表示法显示，具体取决于[`--binary-as-hex`](mysql-command-options.html#option_mysql_binary-as-hex).有关该选项的更多信息，请参阅[第 4.5.1 节，“mysql - MySQL 命令行客户端”](mysql.html).

#### 数据屏蔽功能

本节中的每个函数对其字符串参数执行屏蔽操作并返回屏蔽结果。

-   [](<>) [`mask_inner(*`字符串`*, *`边距1`*, *`边距2`* [, *`掩码字符`*])`](data-masking-functions.html#function_mask-inner)

    [](<>)[](<>)

    屏蔽字符串的内部部分，保持末端不变，并返回结果。可以指定可选的掩码字符。

    论据：

    -   *`字符串`*: 要屏蔽的字符串。

    -   *`边距1`*: 一个非负整数，它指定字符串左端保持未屏蔽的字符数。如果值为 0，则没有左端字符保持未屏蔽。

    -   *`边距2`*: 一个非负整数，指定字符串右端保持不被屏蔽的字符数。如果值为 0，则没有右端字符保持未屏蔽。

    -   *`掩码字符`*：（可选）用于掩码的单个字符。默认是`'X'`如果*`掩码字符`*没有给出。

        掩码字符必须是单字节字符。尝试使用多字节字符会产生错误。

        返回值：

        被屏蔽的字符串，或`空值`如果任一边距为负。

        如果边距值的总和大于参数长度，则不发生掩码并且返回参数不变。

        例子：

    ```
    mysql> SELECT mask_inner('abcdef', 1, 2), mask_inner('abcdef',0, 5);
    +----------------------------+---------------------------+
    | mask_inner('abcdef', 1, 2) | mask_inner('abcdef',0, 5) |
    +----------------------------+---------------------------+
    | aXXXef                     | Xbcdef                    |
    +----------------------------+---------------------------+
    mysql> SELECT mask_inner('abcdef', 1, 2, '*'), mask_inner('abcdef',0, 5, '#');
    +---------------------------------+--------------------------------+
    | mask_inner('abcdef', 1, 2, '*') | mask_inner('abcdef',0, 5, '#') |
    +---------------------------------+--------------------------------+
    | a***ef                          | #bcdef                         |
    +---------------------------------+--------------------------------+
    ```

-   [](<>) [`mask_outer(*`字符串`*, *`边距1`*, *`边距2`* [, *`掩码字符`*])`](data-masking-functions.html#function_mask-outer)

    [](<>)[](<>)

    屏蔽字符串的左右两端，使内部不被屏蔽，并返回结果。可以指定可选的掩码字符。

    论据：

    -   *`字符串`*: 要屏蔽的字符串。

    -   *`边距1`*：一个非负整数，它指定要屏蔽的字符串左端的字符数。如果值为 0，则不屏蔽左端字符。

    -   *`边距2`*: 一个非负整数，指定要屏蔽的字符串右端的字符数。如果值为 0，则不屏蔽右端字符。

    -   *`掩码字符`*：（可选）用于掩码的单个字符。默认是`'X'`如果*`掩码字符`*没有给出。

        掩码字符必须是单字节字符。尝试使用多字节字符会产生错误。

        返回值：

        被屏蔽的字符串，或`空值`如果任一边距为负。

        如果边距值的总和大于参数长度，则整个参数被屏蔽。

        例子：

    ```
    mysql> SELECT mask_outer('abcdef', 1, 2), mask_outer('abcdef',0, 5);
    +----------------------------+---------------------------+
    | mask_outer('abcdef', 1, 2) | mask_outer('abcdef',0, 5) |
    +----------------------------+---------------------------+
    | XbcdXX                     | aXXXXX                    |
    +----------------------------+---------------------------+
    mysql> SELECT mask_outer('abcdef', 1, 2, '*'), mask_outer('abcdef',0, 5, '#');
    +---------------------------------+--------------------------------+
    | mask_outer('abcdef', 1, 2, '*') | mask_outer('abcdef',0, 5, '#') |
    +---------------------------------+--------------------------------+
    | *bcd**                          | a#####                         |
    +---------------------------------+--------------------------------+
    ```

-   [](<>) [`掩码盘（*`字符串`*)`](data-masking-functions.html#function_mask-pan)

    [](<>)[](<>)

    屏蔽支付卡主帐号并返回除最后四位以外的所有数字替换为的号码`'X'`人物。

    论据：

    -   *`字符串`*: 要屏蔽的字符串。该字符串必须是适合主帐号的长度，但不会另外检查。

        返回值：

        作为字符串的掩码付款号码。如果参数比要求的短，则原样返回。

        例子：

    ```
    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX9102        |
    +-------------------------+
    mysql> SELECT mask_pan(gen_rnd_pan(19));
    +---------------------------+
    | mask_pan(gen_rnd_pan(19)) |
    +---------------------------+
    | XXXXXXXXXXXXXXX8268       |
    +---------------------------+
    mysql> SELECT mask_pan('a*Z');
    +-----------------+
    | mask_pan('a*Z') |
    +-----------------+
    | a*Z             |
    +-----------------+
    ```

-   [](<>) [`mask_pan_relaxed(*`字符串`*)`](data-masking-functions.html#function_mask-pan-relaxed)

    [](<>)[](<>)

    屏蔽支付卡主帐号并返回除前六位和后四位之外的所有数字替换为`'X'`人物。前六位数字表示支付卡发卡机构。

    论据：

    -   *`字符串`*: 要屏蔽的字符串。该字符串必须是适合主帐号的长度，但不会另外检查。

        返回值：

        作为字符串的掩码付款号码。如果参数比要求的短，则原样返回。

        例子：

    ```
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 551279XXXXXX3108                |
    +---------------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan(19));
    +-----------------------------------+
    | mask_pan_relaxed(gen_rnd_pan(19)) |
    +-----------------------------------+
    | 462634XXXXXXXXX6739               |
    +-----------------------------------+
    mysql> SELECT mask_pan_relaxed('a*Z');
    +-------------------------+
    | mask_pan_relaxed('a*Z') |
    +-------------------------+
    | a*Z                     |
    +-------------------------+
    ```

-   [](<>) [`mask_ssn(*`字符串`*)`](data-masking-functions.html#function_mask-ssn)

    [](<>)[](<>)

    屏蔽美国社会安全号码并返回除最后四位以外的所有数字替换为的号码`'X'`人物。

    论据：

    -   *`字符串`*: 要屏蔽的字符串。该字符串的长度必须为 11 个字符。

        返回值：

        掩码为字符串的社会安全号码，如果参数的长度不正确，则返回错误。

        例子：

    ```
    mysql> SELECT mask_ssn('909-63-6922'), mask_ssn('abcdefghijk');
    +-------------------------+-------------------------+
    | mask_ssn('909-63-6922') | mask_ssn('abcdefghijk') |
    +-------------------------+-------------------------+
    | XXX-XX-6922             | XXX-XX-hijk             |
    +-------------------------+-------------------------+
    mysql> SELECT mask_ssn('909');
    ERROR 1123 (HY000): Can't initialize function 'mask_ssn'; MASK_SSN: Error:
    String argument width too small
    mysql> SELECT mask_ssn('123456789123456789');
    ERROR 1123 (HY000): Can't initialize function 'mask_ssn'; MASK_SSN: Error:
    String argument width too large
    ```

#### 随机数据生成函数

本节中的函数为不同类型的数据生成随机值。如果可能，生成的值具有为演示或测试值保留的特征，以避免将它们误认为是合法数据。例如，[`gen_rnd_us_phone()`](data-masking-functions.html#function_gen-rnd-us-phone)返回一个使用 555 区号的美国电话号码，实际使用中没有分配给电话号码。单独的功能描述描述了该原则的任何例外情况。

-   [](<>) [`gen_range(*`降低`*, *`上`*)`](data-masking-functions.html#function_gen-range)

    [](<>)[](<>)

    生成从指定范围中选择的随机数。

    论据：

    -   *`降低`*: 一个整数，指定范围的下边界。

    -   *`上`*: 一个整数，指定范围的上边界，不得小于下边界。

        返回值：

        范围内的随机整数*`降低`*到*`上`*, 包含, 或`空值`如果*`上`*参数小于*`降低`*.

        例子：

    ```
    mysql> SELECT gen_range(100, 200), gen_range(-1000, -800);
    +---------------------+------------------------+
    | gen_range(100, 200) | gen_range(-1000, -800) |
    +---------------------+------------------------+
    |                 177 |                   -917 |
    +---------------------+------------------------+
    mysql> SELECT gen_range(1, 0);
    +-----------------+
    | gen_range(1, 0) |
    +-----------------+
    |            NULL |
    +-----------------+
    ```

-   [](<>) [`gen_rnd_email()`](data-masking-functions.html#function_gen-rnd-email)

    [](<>)[](<>)

    在`例子.com`领域。

    论据：

    没有。

    返回值：

    作为字符串的随机电子邮件地址。

    例子：

    ```
    mysql> SELECT gen_rnd_email();
    +---------------------------+
    | gen_rnd_email()           |
    +---------------------------+
    | ijocv.mwvhhuf@example.com |
    +---------------------------+
    ```

-   [](<>) [`gen_rnd_pan([*`尺寸`*])`](data-masking-functions.html#function_gen-rnd-pan)

    [](<>)[](<>)

    生成一个随机支付卡主帐号。该数字通过了 Luhn 校验（一种针对校验位执行校验和验证的算法）。

    警告

    从返回的值[`gen_rnd_pan()`](data-masking-functions.html#function_gen-rnd-pan)应仅用于测试目的，不适合出版。无法保证给定的返回值不会分配给合法的支付账户。是否有必要发布[`gen_rnd_pan()`](data-masking-functions.html#function_gen-rnd-pan)结果，考虑用[`掩码盘（）`](data-masking-functions.html#function_mask-pan)要么[`mask_pan_relaxed()`](data-masking-functions.html#function_mask-pan-relaxed).

    论据：

    -   *`尺寸`*：（可选）指定结果大小的整数。默认为 16，如果*`尺寸`*没有给出。如果给出，*`尺寸`*必须是 12 到 19 范围内的整数。

        返回值：

        作为字符串的随机支付号码，或`空值`如果一个*`尺寸`*给出了允许范围之外的参数。

        例子：

    ```
    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX5805        |
    +-------------------------+
    mysql> SELECT mask_pan(gen_rnd_pan(19));
    +---------------------------+
    | mask_pan(gen_rnd_pan(19)) |
    +---------------------------+
    | XXXXXXXXXXXXXXX5067       |
    +---------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 398403XXXXXX9547                |
    +---------------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan(19));
    +-----------------------------------+
    | mask_pan_relaxed(gen_rnd_pan(19)) |
    +-----------------------------------+
    | 578416XXXXXXXXX6509               |
    +-----------------------------------+
    mysql> SELECT gen_rnd_pan(11), gen_rnd_pan(20);
    +-----------------+-----------------+
    | gen_rnd_pan(11) | gen_rnd_pan(20) |
    +-----------------+-----------------+
    | NULL            | NULL            |
    +-----------------+-----------------+
    ```

-   [](<>) [`gen_rnd_ssn()`](data-masking-functions.html#function_gen-rnd-ssn)

    [](<>)[](<>)

    生成一个随机的美国社会安全号码`*`AAA`*-*`BB`*-*`中国交建`*`格式。这*`AAA`*部分大于 900 并且*`BB`*部分小于 70，这是不用于合法社会安全号码的特征。

    论据：

    没有。

    返回值：

    作为字符串的随机社会安全号码。

    例子：

    ```
    mysql> SELECT gen_rnd_ssn();
    +---------------+
    | gen_rnd_ssn() |
    +---------------+
    | 951-26-0058   |
    +---------------+
    ```

-   [](<>) [`gen_rnd_us_phone()`](data-masking-functions.html#function_gen-rnd-us-phone)

    [](<>)[](<>)

    生成一个随机的美国电话号码`1-555-*`AAA`*-*`BBBB`*`格式。555 区号不用于合法电话号码。

    论据：

    没有。

    返回值：

    一个随机的美国电话号码作为字符串。

    例子：

    ```
    mysql> SELECT gen_rnd_us_phone();
    +--------------------+
    | gen_rnd_us_phone() |
    +--------------------+
    | 1-555-682-5423     |
    +--------------------+
    ```

#### 基于随机数据字典的函数

本节中的函数操作术语字典并基于它们执行生成和屏蔽操作。其中一些功能需要[`极好的`](privileges-provided.html#priv_super)特权。

加载字典时，它成为字典注册表的一部分，并被分配一个名称以供其他字典函数使用。字典是从每行包含一个术语的纯文本文件中加载的。空行被忽略。为了有效，字典文件必须至少包含一个非空行。

-   [](<>) [`gen_blacklist(*`字符串`*, *`字典名`*, *`替换字典名称`*)`](data-masking-functions.html#function_gen-blacklist)

    [](<>)[](<>)

    将一个字典中的术语替换为第二个字典中的术语并返回替换术语。这通过替换掩盖了原始术语。此函数在 MySQL 8.0.23 中已弃用；采用[`gen_blocklist()`](data-masking-functions.html#function_gen-blocklist)反而。

-   [](<>) [`gen_blocklist(*`字符串`*, *`字典名`*, *`替换字典名称`*)`](data-masking-functions.html#function_gen-blocklist)

    [](<>)[](<>)

    将一个字典中的术语替换为第二个字典中的术语并返回替换术语。这通过替换掩盖了原始术语。此功能在 MySQL 8.0.23 中添加；用它代替[`gen_blacklist()`](data-masking-functions.html#function_gen-blacklist).

    论据：

    -   *`字符串`*：表示要替换的术语的字符串。

    -   *`字典名`*：一个字符串，它命名包含要替换的术语的字典。

    -   *`替换字典名称`*：一个字符串，它命名要从中选择替换术语的字典。

        返回值：

        随机选择的字符串*`替换字典名称`*作为替代品*`字符串`*， 要么*`字符串`*如果它没有出现在*`字典名`*， 要么`空值`如果任一字典名称不在字典注册表中。

        如果要替换的术语出现在两个字典中，则返回值可能是相同的术语。

        例子：

    ```
    mysql> SELECT gen_blocklist('Berlin', 'DE_Cities', 'US_Cities');
    +---------------------------------------------------+
    | gen_blocklist('Berlin', 'DE_Cities', 'US_Cities') |
    +---------------------------------------------------+
    | Phoenix                                           |
    +---------------------------------------------------+
    ```

-   [](<>) [`gen_dictionary(*`字典名`*)`](data-masking-functions.html#function_gen-dictionary)

    [](<>)[](<>)

    从字典中返回一个随机词。

    论据：

    -   *`字典名`*：一个字符串，它命名要从中选择术语的字典。

        返回值：

        字典中的随机术语作为字符串，或`空值`如果字典名称不在字典注册表中。

        例子：

    ```
    mysql> SELECT gen_dictionary('mydict');
    +--------------------------+
    | gen_dictionary('mydict') |
    +--------------------------+
    | My term                  |
    +--------------------------+
    mysql> SELECT gen_dictionary('no-such-dict');
    +--------------------------------+
    | gen_dictionary('no-such-dict') |
    +--------------------------------+
    | NULL                           |
    +--------------------------------+
    ```

-   [](<>) [`gen_dictionary_drop(*`字典名`*)`](data-masking-functions.html#function_gen-dictionary-drop)

    [](<>)[](<>)

    从字典注册表中删除字典。

    此功能需要[`极好的`](privileges-provided.html#priv_super)特权。

    论据：

    -   *`字典名`*：一个字符串，用于命名要从字典注册表中删除的字典。

        返回值：

        指示删除操作是否成功的字符串。`字典已删除`表示成功。`字典删除错误`表示失败。

        例子：

    ```
    mysql> SELECT gen_dictionary_drop('mydict');
    +-------------------------------+
    | gen_dictionary_drop('mydict') |
    +-------------------------------+
    | Dictionary removed            |
    +-------------------------------+
    mysql> SELECT gen_dictionary_drop('no-such-dict');
    +-------------------------------------+
    | gen_dictionary_drop('no-such-dict') |
    +-------------------------------------+
    | Dictionary removal error            |
    +-------------------------------------+
    ```

-   [](<>) [`gen_dictionary_load(*`字典路径`*, *`字典名`*)`](data-masking-functions.html#function_gen-dictionary-load)

    [](<>)[](<>)

    将文件加载到字典注册表中，并为字典分配一个名称，以便与需要字典名称参数的其他函数一起使用。

    此功能需要[`极好的`](privileges-provided.html#priv_super)特权。

    重要的

    字典不是持久的。每次服务器启动时都必须加载应用程序使用的任何字典。

    一旦加载到注册表中，即使底层字典文件发生更改，字典也会按原样使用。要重新加载字典，首先将其删除[`gen_dictionary_drop()`](data-masking-functions.html#function_gen-dictionary-drop)，然后再次加载它[`gen_dictionary_load()`](data-masking-functions.html#function_gen-dictionary-load).

    论据：

    -   *`字典路径`*: 一个字符串，指定字典文件的路径名。

    -   *`字典名`*：为字典提供名称的字符串。

        返回值：

        指示加载操作是否成功的字符串。`字典加载成功`表示成功。`字典加载错误`表示失败。字典加载失败可能有多种原因，包括：

    -   已加载具有给定名称的字典。

    -   找不到字典文件。

    -   字典文件不包含术语。

    -   这[`secure_file_priv`](server-system-variables.html#sysvar_secure_file_priv)设置了系统变量，并且字典文件不在该变量命名的目录中。

        例子：

    ```
    mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/mydict','mydict');
    +---------------------------------------------------------------------+
    | gen_dictionary_load('/usr/local/mysql/mysql-files/mydict','mydict') |
    +---------------------------------------------------------------------+
    | Dictionary load success                                             |
    +---------------------------------------------------------------------+
    mysql> SELECT gen_dictionary_load('/dev/null','null');
    +-----------------------------------------+
    | gen_dictionary_load('/dev/null','null') |
    +-----------------------------------------+
    | Dictionary load error                   |
    +-----------------------------------------+
    ```
