校验集装箱号;java校验集装箱号并附解析

需求

其实这是一道算法题:

先看看集装箱编号的规则说明

一、 标准箱号构成基本概念:采用ISO6346(1995)标准。 标准集装箱箱号由11位编码组成,包括三个部分:

1、 第一部分由4位英文字母组成。前三位代码 (Owner Code) 主要说明箱主、经营人,第四位代码说明集装箱的类型。列如CBHU 开头的标准集装箱是表明箱主和经营人为中远集运。

2、 第二部分由6位数字组成。是箱体注册码(Registration Code), 用于一个集装箱箱体持有的唯一标识。

3、 第三部分为校验码(Check Digit)由前4位字母和6位数字经过校验规则运算得到,用于识别在校验时是否发生错误。即第11位数字。 根据校验规则箱号的每个字母和数字都有一个运算的对应值。箱号的前10位字母和数字的对应值从0到Z对应数值为0到38,11、22、33不能对11取模数,所以要除去。

 2、第N位的箱号对应值再分别乘以2N-1 (N=1,2,3………..10) 例如:箱号为CBHU3202732的集装箱它的第1位代码为C, 它的代码值=代码的对应值×21-1 =13×1=13。 类推第2位代码为B  它的代码值=代码的对应值×22-1 =12×2=24

以此类推得到箱号前10位代码的代码值。 将前10位的代码值乘积累加后对11取模 箱号为CBHU3202732的集装箱前10位箱号的代码累加值=4061,取11的模后为2,就是这个箱号第11位的识别码的数值。 以此类推,就能得到校验码   集装箱编号是集装箱全球唯一识别标识   根据ISO6346:1995 《集装箱--代码、识别和标记》标准,集装箱校验码算法如下:   

集装箱编号共11位,前四位是字母,最后一位为校验码,举例如◎◎◎◎×××××××。   字母取数值规则为:A=10,B至K依次取12至21,L至U依次取23至32,V至Z依次取34至38。   箱号第一位的值乘以2的0次幂,第二位乘以2的1次幂,...,第十位乘以2的9次幂,然后求和。   其和除以11的余数即为校验码的值。(注:当余数为10时,校验码也为 

集装箱编号是集装箱全球唯一识别标识   根据ISO6346:1995 《集装箱--代码、识别和标记》标准,集装箱校验码算法如下:   集装箱编号共11位,前四位是字母,最后一位为校验码,举例如◎◎◎◎×××××××。   字母取数值规则为:A=10,B至K依次取12至21,L至U依次取23至32,V至Z依次取34至38。   箱号第一位的值乘以2的0次幂,第二位乘以2的1次幂,...,第十位乘以2的9次幂,然后求和。   其和除以11的余数即为校验码的值。(注:当余数为10时,校验码也为

代码

    @Override
    public void verifyCntrCode(String cntrNo ) throws Exception {

        result.setAck(EnumAck.Failure);
        if (StringUtils.isEmpty(cntrNo)) {
           System.out.println("装箱号不能为空!");
          
        }
        int length = cntrNo.length();
        if (length != 11) {
           System.out.println("总长度非11位长!");
        
        }
        String sub1 = StringUtils.substring(cntrNo, 0, 4);
        if (!sub1.matches("[A-Z]+")) {
            System.out.println("第一部分非大写字母!");
         
        }
        String sub2 = StringUtils.substring(cntrNo, 4, length-1);
        if(!sub2.matches("[0-9]*")){
           System.out.println("第二部分非数字!");
        
        }
        String sub3 = StringUtils.substring(cntrNo,  length-1, length);
        if(!sub3.matches("[0-9]*")){
            System.out.println("第二部分非数字!");
      
        }
        //定义一个字符串,集装箱编号的每个字符必定出自这串字符,其中11,22,33用?代替,获取对应值,满足0-38
        String charCode = "0123456789A?BCDEFGHIJK?LMNOPQRSTU?VWXYZ";
        char[] codeChars = cntrNo.toCharArray();//将接收到的字符串转换为字符数组,方便后续遍历
        int num = 0;//初始化用于规则计算后累计的变量,用于计算结束后%第11位
   
        for (int i = 0; i < 10; i++) {
            int idx = charCode.indexOf(codeChars[i]);//遍历取出第i个字符,并从charCode字符串中查找这个字符所在位置,这个位置的值就是对应值
            if (idx == -1 || charCode.charAt(idx)=='?') {//如果查找不到或者找到替代符号(?)一样,那么这个字符不是规则中所要求的字符,需要校验的字符串不符合集装箱号的规则,退出循环
               System.out.println("不符合集装箱号的规则");
                break;
            }
            idx =  (int) (idx * Math.pow(2, i));//这里的意思应该是说对应值*2的(n-1)次方;原文表达(2、第N位的箱号对应值再分别乘以2N-1 (N=1,2,3………..10))是误导的关键
            num += idx;//累加
        }
        num = (num % 11) % 10;//取模11
       
        if(!Integer.parseInt(String.valueOf(codeChars[10]))== num){
          System.out.println("第11位校验码未通过验证");
        
        }
       System.out.println("验证码全部通过规则验证!");
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值