根据32位主机号生成序列号生成二维码并且上传到OSS存储

发布时间:2024年01月04日

判断输入的主机号是否为32位,如果不等于32位则返回失败;将主机号经过AES加密算法中密钥为“1234567890123456”的ECB模式加密后,用base64编码形式打印,再经过md5加密算法将打印出来的base64编码生成32位散列值,作为用于激活操作系统的序列号,并基于序列号生成相应的二维码。输入的主机号和输出的序列号需要存储到数据库中。(这个二维码是不变的的,变的是二维码里面的内容在本地)

先去创建一个二维码(里面的内容随便照片、文字)

图片二维码生成器_图片二维码在线制作_互联二维码

依赖

       <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.0</version> <!-- 根据最新版本调整 -->
        </dependency>

代码展示

private static final String AES_KEY = "1234567890123456";
    @Override
    public Result<String> generate(String hao) {
        // 验证主机号长度
        if (hao.length() != 32) {
            Result.error("主机号长度不合法,操作失败!");
        }
        // AES加密
        String encryptedHostNumber = encryptAES(hao, AES_KEY);
        // Base64编码
        String base64Encoded = Base64.getEncoder().encodeToString(encryptedHostNumber.getBytes(StandardCharsets.UTF_8));
        // MD5加密
        String md5Hash = generateMD5Hash(base64Encoded);

// 生成二维码(这里省略生成二维码的步骤)
        try {
            // 二维码内容
            String qrCodeData = md5Hash;

            // 设置二维码的宽度和高度
            int width = 300;
            int height = 300;

            // 设置二维码图片保存路径
            String filePath = "之前本地报错的二维码";//自己的


            // 自己的服务器地址
            String endpoint = "";
            // 自己的AccessKeyId
            String accessKeyId = "";
            // 自己的AccessKeySecret
            String accessKeySecret = "";
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            String fileUrl="";
            try {
                File file = new File(filePath);
                String objectName = "aaa.png"; // OSS 对象名称
                // 设置一个字符串变量bucketName,
               String bucketName="";//自己的
                // 上传文件
                ossClient.putObject(bucketName, objectName, file);

                System.out.println("文件上传成功!");

                // 如果需要获取上传后的文件 URL,可以使用以下代码
                 fileUrl = "https://" + bucketName + "." + endpoint + "/" + objectName;
                System.out.println("文件访问地址:" + fileUrl);
            } finally {
                // 关闭 OSS 客户端
                ossClient.shutdown();
            }

            //   存储到数据库
            saveToDatabase(hao, md5Hash,fileUrl);
            System.out.println("操作成功!生成的序列号为:" + md5Hash);

            // 设置二维码图片格式
            String fileType = "png";

            // 创建 BitMatrix 对象
            BitMatrix bitMatrix = new QRCodeWriter().encode(qrCodeData, BarcodeFormat.QR_CODE, width, height);

            // 将 BitMatrix 转换为 BufferedImage
            Path path = Paths.get(filePath);
            MatrixToImageWriter.writeToPath(bitMatrix, fileType, path);

        } catch (WriterException e) {
            throw new RuntimeException("生成二维码失败", e);
        }
        return null;
    }

        public static class MatrixToImageWriter {
            // 定义二维码颜色的常量
            private static final int BLACK = 0xFF000000;  // #00000000
            private static final int WHITE = 0xFFFFFFFF;  // #FFFFFFFF

            // 私有构造函数,防止外部实例化
            private MatrixToImageWriter() {}

            /**
             * 将二维码矩阵写入指定路径的图片文件
             *
             * @param matrix  二维码矩阵
             * @param format 图片格式
             * @param path 图片保存路径
             * @throws RuntimeException 如果写入二维码图片失败,则抛出运行时异常
             */
            public static void writeToPath(BitMatrix matrix, String format, Path path) {
                try {
                    // 创建二维码转换为图片的配置对象
                    MatrixToImageConfig config = new MatrixToImageConfig(BLACK, WHITE);
                    // 将二维码矩阵写入指定路径的图片文件
                    MatrixToImageWriter.writeToPath(matrix, format, path, config);
                } catch (Exception e) {
                    throw new RuntimeException("写入二维码图片失败", e);
                }
            }
            /**
             * 将二维码矩阵写入指定路径的图片文件
             * @param matrix 二维码矩阵
             * @param format 图片格式
             * @param path 图片保存路径
             * @param config 二维码图像配置
             */
            public static void writeToPath(BitMatrix matrix, String format, Path path, MatrixToImageConfig config) {
                try {
                    // 将二维码矩阵转换为缓冲图像
                    BufferedImage image = toBufferedImage(matrix, config);
                    // 将缓冲图像写入指定路径的图片文件
                    if (!ImageIO.write(image, format, path.toFile())) {
                        throw new RuntimeException("写入二维码图片失败");
                    }
                } catch (IOException e) {
                    throw new RuntimeException("写入二维码图片失败", e);
                }
            }
            /**
             * 将二进制矩阵转换为缓冲图像对象
             * @param matrix 二进制矩阵
             * @param config 图像配置
             * @return 缓冲图像对象
             */
            private static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
                // 获取矩阵的宽度和高度
                int width = matrix.getWidth();
                int height = matrix.getHeight();
                // 创建具有指定宽度、高度和颜色模型的缓冲图像对象
                BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                // 遍历矩阵的每个元素
                for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                        // 将矩阵中的元素转换为像素颜色,并存储在图像对象中
                        image.setRGB(x, y, matrix.get(x, y) ? config.getPixelOnColor() : config.getPixelOffColor());
                    }
                }
                // 返回图像对象
                return image;
            }

            public static class MatrixToImageConfig {
                // 用于配置矩阵转换为图像的参数
                private final int onColor; // 亮色
                private final int offColor; // 暗色
                // 构造方法
                public MatrixToImageConfig(int onColor, int offColor) {
                    this.onColor = onColor;
                    this.offColor = offColor;
                }
                // 获取亮色
                public int getPixelOnColor() {
                    return onColor;
                }
                // 获取暗色
                public int getPixelOffColor() {
                    return offColor;
                }
            }
        }

    private static void saveToDatabase(String hostNumber, String serialNumber,String fileUrl) {
        try {
            // 假设你有一个数据库连接,并且有一个表用于存储主机号和序列号
            String jdbcUrl = "jdbc:mysql://自己的服务器ip:3306/自己的库";
            String username = "账号";
            String password = "密码";

            Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
            // 插入数据
            String sql = "要执行的sql";

            try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
                preparedStatement.setString(1, hostNumber);//参数1对应占位符1
                preparedStatement.setString(2, serialNumber);
                preparedStatement.setString(3, fileUrl);
                preparedStatement.executeUpdate();
            }
            connection.close();
        } catch (Exception e) {
            throw new RuntimeException("存储到数据库失败", e);
        }
    }


    private static String encryptAES(String input, String key) {
        try {
            // 使用AES算法创建一个加密器对象
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            // 将key转换为字节数组,并使用UTF-8编码
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            // 初始化加密器,设置为加密模式
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            // 对输入的input进行加密,先将input转换为字节数组,然后使用加密器进行加密,最后将加密结果转换为字符串
            return new String(cipher.doFinal(input.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
        } catch (Exception e) {
            // 如果出现异常,将异常包装成运行时异常并抛出
            throw new RuntimeException("AES加密失败", e);
        }

    }

    private static String generateMD5Hash(String input) {
        try {
            // 创建一个MessageDigest对象,使用MD5算法
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 将输入的字节数据通过MessageDigest算法进行哈希计算
            byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
            // 创建一个StringBuilder对象,用于存储哈希结果的十六进制字符串
            StringBuilder hexString = new StringBuilder();
            // 遍历哈希结果的每个字节
            for (byte b : hashBytes) {
                // 将字节数据转换为十六进制字符串
                String hex = Integer.toHexString(0xFF & b);
                // 如果转换结果长度为1,则在前面添加一个0,保证十六进制字符串长度为2
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                // 将转换后的十六进制字符添加到StringBuilder对象中
                hexString.append(hex);
            }
            // 返回哈希结果的十六进制字符串
            return hexString.toString();
        } catch (Exception e) {
            // 如果发生异常,抛出运行时异常,并设置详细信息为"MD5加密失败",并将原始异常作为原因
            throw new RuntimeException("MD5加密失败", e);
        }

    }

文章来源:https://blog.csdn.net/2301_79455003/article/details/135358124
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。