使用Base64对URL参数编码

在近期的项目中,我们需要将手机号作为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="));
    }
 
13079544-cb0f0358c79b5118.png
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后前端妹子一枚,爱阅读,爱交友,将工作中遇到的问题记录在这里,希望给每一个看到的你能带来一点帮助。
欢迎留言交流。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值