001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.mask;
017
018/**
019 * 内置的数据脱敏方式
020 */
021public class Masks {
022
023    private Masks() {
024    }
025
026    /**
027     * 手机号脱敏
028     */
029    public static final String MOBILE = "mobile";
030
031    /**
032     * 固定电话脱敏
033     */
034    public static final String FIXED_PHONE = "fixed_phone";
035
036    /**
037     * 身份证号脱敏
038     */
039    public static final String ID_CARD_NUMBER = "id_card_number";
040
041    /**
042     * 中文名脱敏
043     */
044    public static final String CHINESE_NAME = "chinese_name";
045
046    /**
047     * 地址脱敏
048     */
049    public static final String ADDRESS = "address";
050
051    /**
052     * 邮件脱敏
053     */
054    public static final String EMAIL = "email";
055
056    /**
057     * 密码脱敏
058     */
059    public static final String PASSWORD = "password";
060
061    /**
062     * 车牌号脱敏
063     */
064    public static final String CAR_LICENSE = "car_license";
065
066    /**
067     * 银行卡号脱敏
068     */
069    public static final String BANK_CARD_NUMBER = "bank_card_number";
070
071
072    private static String createMask(int count) {
073        StringBuilder mask = new StringBuilder();
074        for (int i = 0; i < count; i++) {
075            mask.append("*");
076        }
077        return mask.toString();
078    }
079
080
081    private static String mask(String needToMaskString, int keepFirstCount, int keepLastCount, int maskCount) {
082        return needToMaskString.substring(0, keepFirstCount)
083            + createMask(maskCount)
084            + needToMaskString.substring(needToMaskString.length() - keepLastCount);
085    }
086
087
088    /**
089     * 手机号脱敏处理器
090     * 保留前三后四,中间的为星号  "*"
091     */
092    static MaskProcessor MOBILE_PROCESSOR = data -> {
093        if (data instanceof String && ((String) data).startsWith("1") && ((String) data).length() == 11) {
094            return mask((String) data, 3, 4, 4);
095        }
096        return data;
097    };
098
099
100    /**
101     * 固定电话脱敏
102     * 保留前三后四,中间的为星号  "*"
103     */
104    static MaskProcessor FIXED_PHONE_PROCESSOR = data -> {
105        if (data instanceof String && ((String) data).length() > 5) {
106            return mask((String) data, 3, 2, ((String) data).length() - 5);
107        }
108        return data;
109    };
110
111
112    /**
113     * 身份证号脱敏处理器
114     * 身份证号的保留前三后四,中间的数为星号  "*"
115     */
116    static MaskProcessor ID_CARD_NUMBER_PROCESSOR = data -> {
117        if (data instanceof String && ((String) data).length() >= 15) {
118            return mask((String) data, 3, 4, ((String) data).length() - 7);
119        }
120        return data;
121    };
122
123
124    /**
125     * 姓名脱敏
126     */
127    static MaskProcessor CHINESE_NAME_PROCESSOR = data -> {
128        if (data instanceof String) {
129            String name = (String) data;
130            if (name.length() == 2) {
131                return name.charAt(0) + "*";
132            } else if (name.length() == 3) {
133                return name.charAt(0) + "*" + name.charAt(2);
134            } else if (name.length() == 4) {
135                return "**" + name.substring(2, 4);
136            } else if (name.length() > 4) {
137                return mask(name, 2, 1, name.length() - 3);
138            }
139        }
140        return data;
141    };
142
143
144    /**
145     * 地址脱敏
146     */
147    static MaskProcessor ADDRESS_PROCESSOR = data -> {
148        if (data instanceof String) {
149            String address = (String) data;
150            if (address.length() > 6) {
151                return mask(address, 6, 0, 3);
152            } else if (address.length() > 3) {
153                return mask(address, 3, 0, 3);
154            }
155        }
156        return data;
157    };
158
159
160    /**
161     * email 脱敏
162     */
163    static MaskProcessor EMAIL_PROCESSOR = data -> {
164        if (data instanceof String && ((String) data).contains("@")) {
165            String fullEmail = (String) data;
166            int indexOf = fullEmail.lastIndexOf("@");
167            String email = fullEmail.substring(0, indexOf);
168
169            if (email.length() == 1) {
170                return "*" + fullEmail.substring(indexOf);
171            } else if (email.length() == 2) {
172                return "**" + fullEmail.substring(indexOf);
173            } else if (email.length() < 5) {
174                return mask(email, 2, 0, email.length() - 2) + fullEmail.substring(indexOf);
175            } else {
176                return mask(email, 3, 0, email.length() - 3) + fullEmail.substring(indexOf);
177            }
178        }
179        return data;
180    };
181
182
183    /**
184     * 密码 脱敏
185     */
186    static MaskProcessor PASSWORD_PROCESSOR = data -> {
187        if (data instanceof String) {
188            return mask((String) data, 0, 0, ((String) data).length());
189        }
190        return data;
191    };
192
193
194    /**
195     * 车牌号 脱敏
196     */
197    static MaskProcessor CAR_LICENSE_PROCESSOR = data -> {
198        if (data instanceof String) {
199            return mask((String) data, 3, 1, ((String) data).length() - 4);
200        }
201        return data;
202    };
203
204
205    /**
206     * 银行卡号 脱敏
207     */
208    static MaskProcessor BANK_CARD_PROCESSOR = data -> {
209        if (data instanceof String && ((String) data).length() >= 8) {
210            return mask((String) data, 4, 4, 4);
211        }
212        return data;
213    };
214
215
216}