/* ========================================================= 通用脱敏函数集合 created by: lyl date: 2025-07-24 说明:所有函数统一返回 text,NULL 输入返回 NULL ========================================================= */ -- 1) 缺省规则:保留前 a 位和后 b 位(默认脱敏方式) CREATE OR REPLACE FUNCTION mask(val text, a int, b int) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN val IS NULL THEN NULL WHEN length(val) <= a + b THEN val ELSE substr(val, 1, a) || rpad('*', length(val) - a - b, '*') || substr(val, length(val) - b + 1, b) END; $$; -- 2) 姓名:中文保留最后一个字,英文仅保留首字母 CREATE OR REPLACE FUNCTION mask_name(full_name text) RETURNS text LANGUAGE plpgsql IMMUTABLE STRICT AS $$ DECLARE len int; last_char text; BEGIN IF full_name IS NULL THEN RETURN NULL; END IF; len := length(full_name); IF len = 0 THEN RETURN ''; END IF; -- 判断是否为纯 ASCII,简单认为只要有一个非 ASCII 就是中文 IF full_name ~ '[^\x00-\x7F]' THEN -- 中文规则:保留最后一个字 last_char := substr(full_name, len, 1); RETURN rpad('*', len-1, '*') || last_char; ELSE -- 英文规则:保留首字母 RETURN substr(full_name, 1, 1) || rpad('*', len-1, '*'); END IF; END; $$; -- 3) 昵称:保留第一个字和最后一个字 CREATE OR REPLACE FUNCTION mask_nick(nick text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN nick IS NULL THEN NULL WHEN length(nick) <= 2 THEN nick ELSE substr(nick, 1, 1) || rpad('*', length(nick)-2, '*') || substr(nick, length(nick), 1) END; $$; -- 4) 邮箱:仅保留 @ 及之后内容 CREATE OR REPLACE FUNCTION mask_email(mail text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN mail IS NULL THEN NULL WHEN position('@' in mail) = 0 THEN rpad('*', length(mail), '*') ELSE rpad('*', position('@' in mail) - 1, '*') || substr(mail, position('@' in mail)) END; $$; -- 5) 手机号:保留前三位 + 后两位 CREATE OR REPLACE FUNCTION mask_mobile(phone text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN phone IS NULL THEN NULL WHEN length(phone) < 6 THEN phone ELSE substr(phone, 1, 3) || rpad('*', length(phone)-5, '*') || substr(phone, length(phone)-1, 2) END; $$; -- 6) 固定电话:仅保留后两位 CREATE OR REPLACE FUNCTION mask_tel(tel text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN tel IS NULL THEN NULL WHEN length(tel) < 2 THEN tel ELSE rpad('*', length(tel)-2, '*') || substr(tel, length(tel)-1, 2) END; $$; -- 7) 证件号码:保留第一位和最后一位 CREATE OR REPLACE FUNCTION mask_idcard(id text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN id IS NULL THEN NULL WHEN length(id) <= 2 THEN id ELSE substr(id, 1, 1) || rpad('*', length(id)-2, '*') || substr(id, length(id), 1) END; $$; -- 8) 银行卡:保留前四位和后四位 CREATE OR REPLACE FUNCTION mask_bankcard(card text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN card IS NULL THEN NULL WHEN length(card) <= 8 THEN card ELSE substr(card, 1, 4) || rpad('*', length(card)-8, '*') || substr(card, length(card)-3, 4) END; $$; -- 9) 车牌:保留前两位和最后两位,中间用 * 显示 CREATE OR REPLACE FUNCTION mask_plate(plate text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN plate IS NULL THEN NULL WHEN length(plate) <= 4 THEN plate ELSE substr(plate, 1, 2) || rpad('*', length(plate)-4, '*') || substr(plate, length(plate)-1, 2) END; $$; -- 10) IP 地址:仅保留第一字段,其余替换为 * CREATE OR REPLACE FUNCTION mask_ip(ip text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN ip IS NULL THEN NULL WHEN ip !~ '^([0-9]{1,3}\.){3}[0-9]{1,3}$' THEN rpad('*', length(ip), '*') ELSE split_part(ip, '.', 1) || '.*.*.*' END; $$; -- 11) 数值取整(四舍五入到整数) CREATE OR REPLACE FUNCTION mask_numeric(num numeric) RETURNS numeric LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT round(num); $$; -- 12) 置空:统一替换为 '-' CREATE OR REPLACE FUNCTION mask_blank(val text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT '-'; $$; -- 13) 全遮掩:所有字符替换为 * CREATE OR REPLACE FUNCTION mask_full(val text) RETURNS text LANGUAGE sql IMMUTABLE STRICT AS $$ SELECT CASE WHEN val IS NULL THEN NULL ELSE rpad('*', length(val), '*') END; $$;