二维码一之数据码手工制作(全部手工)

这里只有对数字进行编码(由于只研究几天时间,相较而言这块较容易,主要研究算法去了,如果自己想扩展可以自己写写代码)

示例一:数字编码

在Version 1的尺寸下,纠错级别为H的情况下,编码: 01234567

1. 把上述数字分成三组: 012 345 67

2. 把他们转成二进制:  012 转成 0000001100;  345 转成 0101011001;  67 转成 1000011。

3. 把这三个二进制串起来: 0000001100 0101011001 1000011

4. 把数字的个数转成二进制 (version 1-H是10 bits ): 8个数字的二进制是 0000001000

5. 把数字编码的标志0001和第4步的编码加到前面:  0001 0000001000 0000001100 0101011001 1000011

2.补位

按8bits重排

如果所有的编码加起来不是8个倍数我们还要在后面加上足够的0,比如上面一共有78个bits,所以,我们还要加上2个0,然后按8个bits分好组:

00100000   01011011   00001011   01111000   11010001   01110010   11011100   01001101   01000011   01000000

也就是按8的倍数重排如果不是8的倍数就在后面补0直至8的倍数

然后

"11101100","00010001" 重复添加也就是236 17

剩余位的计算方法等于下图黄色区域的块数除以8 的余数

代码:

package com;
import java.util.regex.Pattern;
/**
 * 二维码数据码生成工具类
 * Created by 常发均 on 2020/5/21.
 */
public class makeDataCode {
    public String data;
    public int jcmDj=2;//Q
    public int[] codeNumTotal=new int[]{26,44,70};
    public int[] codeTcNum=new int[]{10,8,13};
    public int[][] jcCodeNumTotal=new int[][]{{7,10,13,17}};
    public int modeNumber;
    public int[] sjmArr;
    public int jcmNum;
    /*
    * 码字总数v1  26  v2  44  v3  70
    * */
    //19  16  13  9
    /**
     * 1 表示Numeric mode 数字编码
     * 2 表示Byte mode, 字节编码
     * 3 表示中文编码
     * 其他的 不想搞了
     */
    public makeDataCode(){}
    public makeDataCode(String data){
     this.data=data;
        if(data.matches("^\\d+$")){
            modeNumber=1;
            getNumArr();
        }else if(isContainChinese(data)){
            modeNumber=3;
        }else{
            modeNumber=2;
        }
        this.jcmNum=jcCodeNumTotal[0][jcmDj];
    }
    public makeDataCode(String data, String dj){
        this.data=data;
        if(dj.equals("L")){
            this.jcmDj=0;
        }else if(dj.equals("M")){
            this.jcmDj=1;
        }else if(dj.equals("H")){
            this.jcmDj=3;
        }
        this.jcmNum=jcCodeNumTotal[0][jcmDj];
        if(data.matches("^\\d+$")){
            modeNumber=1;
            getNumArr();
        }else if(isContainChinese(data)){
            modeNumber=3;
        }else{
            modeNumber=2;
        }
    }
    public void getNumArr(){
        sjmArr=new int[codeNumTotal[0]-jcmNum];
        StringBuffer sbf=new StringBuffer("0001");
        sbf.append(numToEjzQbl(String.valueOf(data.length())));
        for(int i=0;i<data.length();i+=3){
            if(i>data.length()-3){
                int length=(data.length()-i)*3+1;
                String a=sjzZejz(Integer.valueOf(data.substring(i,data.length())));
                for(int j=0;j<length-a.length();j++){
                    a="0"+a;
                }
                sbf.append(a);
                continue;
            }
            sbf.append(numToEjzQbl(data.substring(i,i+3)));
       }
        if((sbf.length()%8)!=0){
            for(int i=1;i<=(sbf.length()%8);i++){
                sbf.append("0");
            }
        }
        for(int i=0;i<sjmArr.length;i++){
        if(8*i+8<=sbf.length()){
            sjmArr[i]=Integer.parseInt(sbf.substring(8*i,8*i+8),2);
        }else{
            int m=(i-sbf.length()/8)%2;
            if(m==0){
                sjmArr[i]=236;
            }else{
                sjmArr[i]=17;
            }
        }
        }
        for(int i=0;i<sjmArr.length;i++){
            System.out.print(sjmArr[i]+"    ");
        }
    }
    /*
    * 数字转换为二进制不足前补零
    * */
    public String numToEjzQbl(String code){
        String a=sjzZejz(Integer.valueOf(code));
        String b=a;
        for(int j=0;j<codeTcNum[modeNumber-1]-a.length();j++){
            b="0"+b;
        }
        return b;
    }
    /*
    * 十进制转换成二进制
    * */
    public String sjzZejz(int num){
       String str="";
        do{
            str = num % 2 + str;
            num = num / 2;
        }while(num!=0);
        return str;
    }
    public  boolean isContainChinese(String str) {
        return Pattern.compile("[\\u4e00-\\u9fa5]").matcher(str).find()?true:false;
    }
    public static void main(String[] args) {
        makeDataCde d1=new makeDataCde("01234567","H");
    }
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值