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    public static final String MOBILE = "mobile";
029
030    /**
031     * 固定电话脱敏
032     */
033    public static final String FIXED_PHONE = "fixed_phone";
034
035    /**
036     * 身份证号脱敏
037     */
038    public static final String ID_CARD_NUMBER = "id_card_number";
039
040    /**
041     * 中文名脱敏
042     */
043    public static final String CHINESE_NAME = "chinese_name";
044
045    /**
046     * 地址脱敏
047     */
048    public static final String ADDRESS = "address";
049
050    /**
051     * 邮件脱敏
052     */
053    public static final String EMAIL = "email";
054
055    /**
056     * 密码脱敏
057     */
058    public static final String PASSWORD = "password";
059
060    /**
061     * 车牌号脱敏
062     */
063    public static final String CAR_LICENSE = "car_license";
064
065    /**
066     * 银行卡号脱敏
067     */
068    public static final String BANK_CARD_NUMBER = "bank_card_number";
069
070
071    private static String createMask(int count) {
072        StringBuilder mask = new StringBuilder();
073        for (int i = 0; i < count; i++) {
074            mask.append("*");
075        }
076        return mask.toString();
077    }
078
079
080    private static String mask(String needToMaskString, int keepFirstCount, int keepLastCount, int maskCount) {
081        return needToMaskString.substring(0, keepFirstCount)
082                + createMask(maskCount)
083                + needToMaskString.substring(needToMaskString.length() - keepLastCount);
084    }
085
086
087    /**
088     * 手机号脱敏处理器
089     * 保留前三后四,中间的为星号  "*"
090     */
091    static MaskProcessor MOBILE_PROCESSOR = data -> {
092        if (data instanceof String && ((String) data).startsWith("1") && ((String) data).length() == 11) {
093            return mask((String) data, 3, 4, 4);
094        }
095        return data;
096    };
097
098
099    /**
100     * 固定电话脱敏
101     * 保留前三后四,中间的为星号  "*"
102     */
103    static MaskProcessor FIXED_PHONE_PROCESSOR = data -> {
104        if (data instanceof String && ((String) data).length() > 5) {
105            return mask((String) data, 3, 2, ((String) data).length() - 5);
106        }
107        return data;
108    };
109
110
111    /**
112     * 身份证号脱敏处理器
113     * 身份证号的保留前三后四,中间的数为星号  "*"
114     */
115    static MaskProcessor ID_CARD_NUMBER_PROCESSOR = data -> {
116        if (data instanceof String && ((String) data).length() >= 15) {
117            return mask((String) data, 3, 4, ((String) data).length() - 7);
118        }
119        return data;
120    };
121
122
123    /**
124     * 姓名脱敏
125     */
126    static MaskProcessor CHINESE_NAME_PROCESSOR = data -> {
127        if (data instanceof String) {
128            String name = (String) data;
129            if (name.length() == 2) {
130                return name.charAt(0) + "*";
131            } else if (name.length() == 3) {
132                return name.charAt(0) + "*" + name.charAt(2);
133            } else if (name.length() == 4) {
134                return "**" + name.substring(2, 4);
135            } else if (name.length() > 4) {
136                return mask(name, 2, 1, name.length() - 3);
137            }
138        }
139        return data;
140    };
141
142
143    /**
144     * 地址脱敏
145     */
146    static MaskProcessor ADDRESS_PROCESSOR = data -> {
147        if (data instanceof String) {
148            String address = (String) data;
149            if (address.length() > 6) {
150                return mask(address, 6, 0, 3);
151            } else if (address.length() > 3) {
152                return mask(address, 3, 0, 3);
153            }
154        }
155        return data;
156    };
157
158
159    /**
160     * email 脱敏
161     */
162    static MaskProcessor EMAIL_PROCESSOR = data -> {
163        if (data instanceof String && ((String) data).contains("@")) {
164            String fullEmail = (String) data;
165            int indexOf = fullEmail.lastIndexOf("@");
166            String email = fullEmail.substring(0, indexOf);
167
168            if (email.length() == 1) {
169                return "*" + fullEmail.substring(indexOf);
170            } else if (email.length() == 2) {
171                return "**" + fullEmail.substring(indexOf);
172            } else if (email.length() < 5) {
173                return mask(email, 2, 0, email.length() - 2) + fullEmail.substring(indexOf);
174            } else {
175                return mask(email, 3, 0, email.length() - 3) + fullEmail.substring(indexOf);
176            }
177        }
178        return data;
179    };
180
181
182    /**
183     * 密码 脱敏
184     */
185    static MaskProcessor PASSWORD_PROCESSOR = data -> {
186        if (data instanceof String ) {
187            return mask((String) data, 0, 0, ((String) data).length()) ;
188        }
189        return data;
190    };
191
192
193    /**
194     * 车牌号 脱敏
195     */
196    static MaskProcessor CAR_LICENSE_PROCESSOR = data -> {
197        if (data instanceof String) {
198            return mask((String) data, 3, 1, ((String) data).length() - 4);
199        }
200        return data;
201    };
202
203
204    /**
205     * 银行卡号 脱敏
206     */
207    static MaskProcessor BANK_CARD_PROCESSOR = data -> {
208        if (data instanceof String && ((String) data).length() >= 8) {
209            return mask((String) data, 4, 4, 4);
210        }
211        return data;
212    };
213
214
215}