电子签章

Java电子签章生成器

对于菜鸟级别的开发来说(@本人),可能连电子签章还搞不明白是什么东西,直接贴代码,看效果就知道了!

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;

public class SealUtils {
    private static final int CANVAS_SIZE = 300; // 画布宽
    private static final String FONT_FAMILY = "宋体"; // 字体
    //private static final String FOOT_TXT = "电子签约专用章";// 底部文字
    private static final String FOOT_TXT = "别在这里跟我皮";// 底部文字
    private static final String STAR = "★";

    private static int STAR_SIZE = (int) (CANVAS_SIZE / 3.2); // 五角星大小
    private static int FOOT_FONT_SIZE = CANVAS_SIZE / 12; // 底部文字大小

    /**
     * 根据companyName获得合同专用章
     *
     * @param companyName
     * @return
     */
    public static BufferedImage genSealImage(String companyName) {
        BufferedImage bi = new BufferedImage(CANVAS_SIZE, CANVAS_SIZE, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g2d = bi.createGraphics();
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0));
        g2d.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);

        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1));
        int circleRadius = CANVAS_SIZE / 2 - 10;
        drawCicle(g2d, circleRadius);
        drawStar(g2d, circleRadius);
        drawFootText(g2d, circleRadius);
        drwaHeadText(companyName, g2d, circleRadius);

        g2d.dispose();
        return bi;
    }

    public static void main(String[] args) {
        try {
            String name="xxx"; //生成签章名称
            byte[] img= SealUtils.genSealData(name);
            byte2File(img,"D:\\test\\",name+".png");
        } catch (IOException e) {
// TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 辅助方法,byte数组保存为本地文件
     * @param buf
     * @param filePath
     * @param fileName
     */
    private static void byte2File(byte[] buf, String filePath, String fileName)
    {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try
        {
            File dir = new File(filePath);
            if (!dir.exists())
            {
                dir.mkdirs();
            }
            file = new File(filePath + File.separator + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(buf);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (bos != null)
            {
                try
                {
                    bos.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            if (fos != null)
            {
                try
                {
                    fos.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 根据companyName获得合同专用章
     *
     * @param companyName
     * @return
     * @throws IOException
     */
    public static byte[] genSealData(String companyName) throws IOException {
        BufferedImage image = genSealImage(companyName);
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", outStream);
        }
        catch (IOException e) {
            throw e;
        }
        finally {
            try {
                outStream.close();
            }
            catch (IOException e) {
            }
        }
        byte[] imageData = outStream.toByteArray();
        return imageData;
    }


    /**
     * 弧形绘制顶部名称
     *
     * @param companyName
     * @param g2d
     * @param circleRadius
     */
    private static void drwaHeadText(String companyName, Graphics2D g2d, int circleRadius) {
        int companyNameLen = companyName.length();
        int headFontSize;
        if (companyNameLen < 8) { // 字体根据画布大小微调出来的
            headFontSize = 47;
        }
        else {
            headFontSize = 43 - (companyNameLen - 8) * 2;
        }


        Font f;
        FontRenderContext context;
        Rectangle2D rectangle;
        f = new Font(FONT_FAMILY, Font.PLAIN, headFontSize);
        context = g2d.getFontRenderContext();
        rectangle = f.getStringBounds(companyName, context);


        double interval; // 文字之间间距
        if (companyNameLen == 1) {
            interval = 0;
        }
        else {
            interval = rectangle.getWidth() / (companyNameLen - 1) * 0.9;
        }


        double newRadius = circleRadius + rectangle.getY() - 10; // bounds.getY()是负数,这样可以将弧形文字固定在圆内了。-10目的是离圆环稍远一点
        double radianPerInterval = 2 * Math.asin(interval / (2 * newRadius)); // 每个间距对应的角度


        // 第一个元素的角度
        double firstAngle;
        if (companyNameLen % 2 == 1) {
            firstAngle = (companyNameLen - 1) * radianPerInterval / 2.0 + Math.PI / 2 + 0.18; // 0.18是浮点计算误差,如果文字不对称,可以微调
        }
        else {
            firstAngle = (companyNameLen / 2.0 - 1) * radianPerInterval + radianPerInterval / 2.0 + Math.PI / 2 + 0.18;
        }


        for (int i = 0; i < companyNameLen; i++) {
            double theta = firstAngle - i * radianPerInterval;
            double thetaX = newRadius * Math.sin(Math.PI / 2 - theta); // 小小的trick,将【0,pi】区间变换到[pi/2,-pi/2]区间
            double thetaY = newRadius * Math.cos(theta - Math.PI / 2); // 同上类似,这样处理就不必再考虑正负的问题了
            AffineTransform transform = AffineTransform.getRotateInstance(Math.PI / 2 - theta);
            Font f2 = f.deriveFont(transform);
            g2d.setFont(f2);
            g2d.drawString(companyName.substring(i, i + 1), (float) (circleRadius + thetaX + 10), (float) (circleRadius - thetaY + 10));
        }
    }


    /**
     * 画底部文字
     *
     * @param g2d
     * @param circleRadius
     */
    private static void drawFootText(Graphics2D g2d, int circleRadius) {
        Font f;
        FontRenderContext context;
        Rectangle2D rectangle;
        f = new Font(FONT_FAMILY, Font.BOLD, FOOT_FONT_SIZE);
        context = g2d.getFontRenderContext();
        rectangle = f.getStringBounds(FOOT_TXT, context);
        int a = 10 * CANVAS_SIZE / 350; // 底部文字距中心的距离,这是调出来的
        g2d.setFont(f);
        g2d.drawString(FOOT_TXT, (float) (circleRadius + a - rectangle.getCenterX()), (float) (circleRadius * 1.5 + a - rectangle.getCenterY()));
    }


    /**
     * 画中心的 ★
     *
     * @param g2d
     * @param circleRadius
     */
    private static void drawStar(Graphics2D g2d, int circleRadius) {
        Font f = new Font(FONT_FAMILY, Font.PLAIN, STAR_SIZE);
        FontRenderContext context = g2d.getFontRenderContext();
        Rectangle2D rectangle = f.getStringBounds(STAR, context);
        g2d.setFont(f);
        g2d.drawString(STAR, (float) (circleRadius + 10 - rectangle.getCenterX()), (float) (circleRadius + 10 - rectangle.getCenterY()));
    }


    /**
     * 画外圈圆
     *
     * @param g2d
     * @param circleRadius
     */
    private static void drawCicle(Graphics2D g2d, int circleRadius) {
        g2d.setPaint(Color.red);
        int lineSize = circleRadius * 2 / (35); // 圆线条粗细是圆直径的1/35
        g2d.setStroke(new BasicStroke(lineSize));
        Shape circle = new Arc2D.Double(10, 10, circleRadius * 2, circleRadius * 2, 0, 360, Arc2D.OPEN);
        g2d.draw(circle);
    }
}
<think>好的,我需要回答用户关于电子签章和电子签名的定义及区别的问题。首先,我需要回顾用户提供的引用资料,确保信息准确。 根据引用[1],电子签名和数字签名是不同的,数字签名属于电子签名技术的一种。用户提到的电子签章在引用[2]中被解释为电子签名的可视化形式,结合了传统印章的外观和电子签名的技术。而引用[3]指出可靠的电子签名与手写签名具有同等法律效力。 接下来,我需要将这些信息结构化。先分别定义电子签名和电子签章,然后比较它们的区别。需要注意电子签章不仅包含可视化部分,还有隐藏的电子签名技术。同时,法律效力的部分需要引用[3]中的内容。 需要确保术语使用正确,比如数字签名是电子签名的一种。同时,回答要符合用户的要求,使用中文,行内公式正确(虽然这个问题可能不涉及数学公式,但保持警惕),结构清晰,并生成相关问题。 最后,生成的相关问题要围绕电子签章的应用、法律效力以及数字签名的实现技术等方面,确保问题与主题相关,并引导进一步学习。</think>### 电子签章与电子签名的定义及区别 #### 1. **电子签名的定义** 电子签名是一种以电子形式存在、依附于电子文件并用于识别签署人身份的技术手段。其核心功能是保证数据的完整性和签署行为的不可抵赖性。根据《电子签名法》,可靠的电子签名与手写签名或盖章具有同等法律效力[^3]。 从技术角度看,**数字签名**是电子签名的一种实现方式,通过非对称加密技术(例如RSA算法)生成签名值。例如,签名过程可表示为: $$ S = \text{Sign}(M, K_{priv}) $$ 其中$M$为文件内容,$K_{priv}$为私钥,$S$为生成的签名值。 #### 2. **电子签章的定义** 电子签章是电子签名的可视化表现形式,它将传统物理印章或手写签名的图形元素与电子签名技术结合。其作用包括: - 在电子文件中显示印章或签名图像; - 通过隐藏的电子签名技术验证签署人身份和文件完整性[^2]。 #### 3. **两者的核心区别** | **对比项** | **电子签名** | **电子签章** | |------------------|----------------------------------|----------------------------------| | 表现形式 | 纯技术手段(如加密数据) | 可视化图形+电子签名技术 | | 法律效力依据 | 依赖加密算法和证书体系 | 依赖电子签名技术支撑 | | 适用场景 | 广义的电子文件签署 | 需体现传统盖章习惯的场景(如合同)| #### 4. **关键补充说明** - 电子签章的有效性依赖于底层的电子签名技术,仅有图形印章而无数字签名的文件不具备法律效力。 - 数字签名通过哈希函数(如$H(M) = \text{SHA-256}(M)$)确保文件内容未被篡改[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值