国税总局发票助手二维码生成的CRC计算

最近为了在我们的应用里生成发票信息的二维码,根据国税总局的二维码文档(见文后),唯一麻烦的地方就是需要计算一个CRC16的值。中间主要碰到了两个问题,一是文档中没有描述中文编码方式,经过试验,我们发现编码方式应为GBK。二是CRC值的生成,网上找了一些代码,生成的CRC16总是和总局发票助手生成的CRC16不一样。最后还是自己根据以下算法写了一个:


1)将字节流的前2字节放入一个长度为16的寄存器(int);
2)如果寄存器的首位为1,将寄存器左移1位(寄存器的最低位从下一个字节获得),再与生成多项式的简记式(CRC16的生成多项式简记式为0x8005)异或;
    否则仅将寄存器左移1位(寄存器的最低位从下一个字节获得);
3)重复第2步,直到字节流全部移入寄存器;
4)最后补充2个0字节,重复第二步
5)寄存器中的值则为CRC校验码。


示例代码如下

    private int crc16 = 0x8005;
    private int a = 0x0000;    

    public void testCRC() throws UnsupportedEncodingException {
        String input = "杭州XX科技有限公司</>9133XXXXXX92XXX9X</>杭州市滨江区XXXxxx号xx大厦x层xxx室</>xxx股份有限公司xxxx</>";

        byte[] inputs = input.getBytes("GBK");

        for (int i = 0; i < inputs.length; i ++) {
            div(inputs[i]);
        }

        byte r = 0;
        div(r);
        div(r);

        System.out.println(Integer.toHexString(a));
    }

    private void div(byte input) {
        int temp;
        int data = input;
        for (int i = 0; i < 8; i ++) {
            temp = a & 0x8000;
            a = a << 1;
            a = a & 0x0000ffff;

           int numIn = data & 0x80;
           numIn = numIn >> 7;

           a = a ^ numIn;

           if (temp == 0x8000) {
               a = a ^ crc16;
           }

           data = data << 1;
           a = a & 0x0000ffff;
        }
    }


附国税总局便捷开票二维码应用规范:

便捷开票二维码应用规范

为便捷纳税人开具增值税发票,提高发票开具效率和准确性,参照国家相关标准,采用QR码码制,制定本应用规范。

一、编码要求

(一)二维码编码格式采用信息容量大、可靠性高、保密防伪性强的QR码码制。

(二)本规范中QR码符号规格采用版本12(小于等于419字符)、18(大于419字符,小于等于816字符)和25(大于816字符,小于等于1451字符)规格,并根据内容长度自动匹配。

(三)本规范中QR码纠错信息能力等级采用M级别,可纠错15%的数据码字。

(四)本规范中的QR码编码字符集采用字母、数字、中文汉字方式进行编码。


二、编码内容和格式

便捷开票二维码编码内容如下:

索引名称字符长度说明
1起始符1特殊字符“$”表示开始
2版本号2固定值01
3分隔符3用英文半角“</>”组成分隔符,起始符与版本号之间、版本号与名称、CRC与结束符之间不使用分隔符
4名称100变长字段,最大长度为100字符(50个汉字)
5纳税人识别号20变长字段,15至20字符。
6地址电话100变长字段,最大长度为100字符(50个汉字)
7开户行及账号100变长字段,最大长度为100字符(50个汉字)
8CRC及CRC16算法4CRC标识符为4字符。从第四位开始到CRC标识符之前所有内容,包括“</>”分隔符采用CRC-16算法。具体算法:P(X)=X16+X15+X2+1高位在前,低位在后
9结束符1使用特殊字符“$”表示结束符

便捷开票二维码内容格式如下: 起始符+版本号+base64(名称</>纳税人识别号</>地址电话</>开户行及账号</>CRC)+结束符 

 三、打印和显示要求 

 打印和显示二维码时,需遵循二维码大小、缩放比例的格式编排。

(一)二维码图案大小 二维码图案大小的高度、宽度不小于2.0CM×2.0CM。

(二)二维码周边留白区域 二维码周围的空白区域宽度至少要大于10个码元宽度。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
您好!要生成Java国税发票二维码,您可以使用一些开源的Java库来实现。其中,Zxing是一个非常流行的二维码生成库,可以用于在Java中生成二维码。 首先,您需要在您的项目中添加Zxing库的依赖。您可以在Maven或Gradle中添加以下依赖: Maven: ```xml <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.4.1</version> </dependency> ``` Gradle: ```groovy dependencies { implementation 'com.google.zxing:core:3.4.1' } ``` 接下来,您可以使用以下代码生成二维码: ```java import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.common.BitMatrix; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class QRCodeGenerator { public static void main(String[] args) { String invoiceCode = "YOUR_INVOICE_CODE"; // 替换为您的发票代码 String invoiceNumber = "YOUR_INVOICE_NUMBER"; // 替换为您的发票号码 String content = "http://fpcy.gd-n-tax.gov.cn/WebQuery/validate?fpdm=" + invoiceCode + "&fphm=" + invoiceNumber; int width = 300; // 二维码的宽度 int height = 300; // 二维码度 String format = "png"; // 二维码的格式 Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); try { BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints); // 生成二维码的保存路径和文件名 Path filePath = Paths.get("path/to/save", "qrcode.png"); File outputFile = filePath.toFile(); MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile); System.out.println("二维码生成成功!"); } catch (Exception e) { System.out.println("二维码生成失败:" + e.getMessage()); } } } ``` 请注意,在上面的代码中,您需要将`YOUR_INVOICE_CODE`和`YOUR_INVOICE_NUMBER`替换为您的发票代码和发票号码。此外,您还需要指定生成的二维码的保存路径和文件名。 运行上述代码后,将会在指定的路径生成一个名为`qrcode.png`的二维码图片。 希望这可以帮助到您!如果您有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅帅兔子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值