JAVA
采用itextpdf开源框架,此框架并没有提供骑缝签的方案,目前采用循环单页签实现,效果如图:
C++
采用修改底层开源框架的方式,无需循环对多条分割后的章模一次完成签名,效果如图:
从上来看,java与c++的实现效果是一致的,但问题在于java采用的是循环方式,在页数较多的情况下性能较差。
签章原理及优化方案
如图:
由页面对象引用注释层,注释层包含章模图像层与签章字典,章模图像层中的/AP域即是章模所对应的图像对象,而签章字典中的/Contents域即为签名结果数据。
由此得出java骑缝签的优化思路是:根据分割后的章模创建多个不同的章模图像层,并与同一个签章字典进行关联引用。而itextpdf当前版本只支持一个签章字典与一个或者多个相同的章模图像层进行关联,因此需要修改其源代码以支持与多个不同的章模图像层进行关联。
优化前后性能比较
优化前的循环签章的代码片段如下:
优化后的代码片段:
优优后IyinMakeSignature.signDetached方法由循环体内移到了循环体外,对多个不同图片的章模图像层引用只进行一次签名后即可关联到同一个签章字典上。
对一个总页数为42页的PDF文件进行骑缝签,优化前和优化后各运行三次所用的时间比较如下:(注意:此时间由上述代码中log.info(PERFORATION_CODE_TIME处输出,不包括对文件流进行BASE64处理以及网络传输时间)
| 优化前(秒) | 优化后(秒) |
第一次 | 6.295 | 0.199 |
第二次 | 6.092 | 0.184 |
第三次 | 5.730 | 0.142 |