在近期的项目中,我们需要将手机号作为URL中的参数,类似:http://www.***.com/18200001234
这种,但是手机号这样明文显示又不太安全,为防止用户恶意篡改URL的参数,于是就选择用Base64进行编码了。
Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。
有时候我们在Url传递的参数包含特殊字符“+”,“/”,“=”时,这些字符作为参数是不能正常接收的,或者我们的参数包含了用户的信息比如手机号、用户id等,我们不想明文显示,这时候都可以使用base64编码。
编码使用到的工具类Base64Utils。它是Spring-core中提供的,在spring-core.jar中的org.springframework.util包下,它下面常用的工具类还有:StringUtils、ObjectUtils、NumberUtils等。
首先验证手机号参数的规范性:
/*校验手机号正则表达式*/
final static Pattern PHONE_PATTERN = Pattern.compile("^1(3[0-9]|4[57]|5[0-35-9]|6[0-9]|7[0-9]|8[0-9]|9[8-9])\\d{8}$");
public static boolean verifyPhone(String tephone){
if (tephone == null || "".equals(tephone)) {
return false;
}
Matcher m = PHONE_PATTERN.matcher(tephone);
return m.matches();
}
验证通过后对手机号进行编码:
定义一个和手机号长度11位相同长度的字节数组,数组里的字符可以是a-z、0-9的任意字符,并且使用异或的规则编码,保证URL解析不发生异常采取“url safe”编码方式
/**
* 通过手机号获取手机号对应的编码code
* @param phone
* @return
*/
public static String getLinkByPhone(String phone){
byte []key = {'A','B','C','D','E','F','G','H', 'I', 'J', 'K'};
byte []temp = new byte[11];
if(verifyPhone(phone)){
for (int i = 0; i < phone.length(); i++) {
temp[i] = (byte)(key[i] ^ phone.charAt(i));
}
}
return Base64Utils.encodeToUrlSafeString(temp);
}
然后根据编码的规则定义解码规则:
同样,定义一个和手机号长度11位相同长度的字节数组,为防止数组越界抛异常我们需要校验参数的合法性
/**
* 通过编码后的字符获取对应的手机号
* @param code
* @return
*/
public static String getPhoneByLink(String code){
byte []temp = new byte[11];
try {
byte []key = {'A','B','C','D','E','F','G','H', 'I', 'J', 'K'};
if(StringUtils.isNotBlank(code)){
byte []phoneByte = Base64Utils.decodeFromUrlSafeString(code);
if(phoneByte != null && phoneByte.length > 0 && phoneByte.length <= 11 ){
for (int i = 0; i < phoneByte.length; i++) {
temp[i] = (byte)(key[i] ^ phoneByte[i]);
}
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
return new String(temp);
}
}
最后运行结果:
public static void main(String args[]){
System.out.println("对手机号编码后:"+getLinkByPhone("18200001234"));
System.out.println("解码后的手机号:"+getPhoneByLink("cHpxdHV2d3l7eX8="));
}
base64对手机号编码解码结果
编码字符串最后的"="是补齐,因为base64编码后的字符长度应该是4的倍数,不足的话会使用“=”号补齐,如果不喜欢这个“=”号我们可以过滤掉,如下:
public static String getLinkByPhone(String phone){
byte []key = {'A','B','C','D','E','F','G','H', 'I', 'J', 'K'};
byte []temp = new byte[11];
if(verifyPhone(phone)){
for (int i = 0; i < phone.length(); i++) {
temp[i] = (byte)(key[i] ^ phone.charAt(i));
}
}
/*去掉最后补齐的=符号*/
String result = Base64Utils.encodeToUrlSafeString(temp);
return result.substring(0,result.length()-1);
}
总结:
Base64编码是从二进制到字符的转换过程,并不是真正的加密方式,说Base64编码是加密方法,只是因为经过Base64编码之后,让人一眼看上去不知道什么内容而已。
关于将手机号转换成加密字符串的方式还有很多,这里只是一种方法的记录。
原文作者技术博客:https://www.jianshu.com/u/ac4daaeecdfe
95后前端妹子一枚,爱阅读,爱交友,将工作中遇到的问题记录在这里,希望给每一个看到的你能带来一点帮助。
欢迎留言交流。
网友评论