美文网首页架构
spring项目结构设计-验证码工具类

spring项目结构设计-验证码工具类

作者: jinelei | 来源:发表于2020-05-13 17:36 被阅读0次

    注意:这里是依赖awt的

    object VerifyCodeUtils {
        //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
        const val VERIFY_CODES = "0123456789"
        private val random: Random = Random()
        /**
         * 使用指定源生成验证码
         *
         * @param verifySize 验证码长度
         * @param sources    验证码字符源
         * @return
         */
        /**
         * 使用系统默认字符源生成验证码
         *
         * @param verifySize 验证码长度
         * @return
         */
        @JvmOverloads
        fun generateVerifyCode(verifySize: Int, sourceCode: String? = VERIFY_CODES): String {
            var sources = sourceCode
            if (sources == null || sources.length == 0) {
                sources = VERIFY_CODES
            }
            val codesLen = sources.length
            val rand = Random(System.currentTimeMillis())
            val verifyCode = StringBuilder(verifySize)
            for (i in 0 until verifySize) {
                verifyCode.append(sources[rand.nextInt(codesLen - 1)])
            }
            return verifyCode.toString()
        }
    
        /**
         * 生成随机验证码文件,并返回验证码值
         *
         * @param w
         * @param h
         * @param outputFile
         * @param verifySize
         * @return
         * @throws IOException
         */
        @Throws(IOException::class)
        fun outputVerifyImage(w: Int, h: Int, outputFile: File?, verifySize: Int): String {
            val verifyCode = generateVerifyCode(verifySize)
            outputImage(w, h, outputFile, verifyCode)
            return verifyCode
        }
    
        /**
         * 输出随机验证码图片流,并返回验证码值
         *
         * @param w
         * @param h
         * @param os
         * @param verifySize
         * @return
         * @throws IOException
         */
        @Throws(IOException::class)
        fun outputVerifyImage(w: Int, h: Int, os: OutputStream?, verifySize: Int): String {
            val verifyCode = generateVerifyCode(verifySize)
            outputImage(w, h, os, verifyCode)
            return verifyCode
        }
    
        /**
         * 生成指定验证码图像文件
         *
         * @param w
         * @param h
         * @param outputFile
         * @param code
         * @throws IOException
         */
        @Throws(IOException::class)
        fun outputImage(w: Int, h: Int, outputFile: File?, code: String?) {
            if (outputFile == null) {
                return
            }
            val dir: File = outputFile.getParentFile()
            if (!dir.exists()) {
                dir.mkdirs()
            }
            try {
                outputFile.createNewFile()
                val fos = FileOutputStream(outputFile)
                outputImage(w, h, fos, code!!)
                fos.close()
            } catch (e: IOException) {
                throw e
            }
        }
    
        /**
         * 输出指定验证码图片流
         *
         * @param w
         * @param h
         * @param os
         * @param code
         * @throws IOException
         */
        @Throws(IOException::class)
        fun outputImage(w: Int, h: Int, os: OutputStream?, code: String) {
            val verifySize = code.length
            val image = BufferedImage(w, h, BufferedImage.TYPE_INT_RGB)
            val rand = Random()
            val g2 = image.createGraphics()
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
            val colors: Array<Color?> = arrayOfNulls<Color>(5)
            val colorSpaces: Array<Color> = arrayOf<Color>(Color.WHITE, Color.CYAN,
                    Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
                    Color.PINK, Color.YELLOW)
            val fractions = FloatArray(colors.size)
            for (i in colors.indices) {
                colors[i] = colorSpaces[rand.nextInt(colorSpaces.size)]
                fractions[i] = rand.nextFloat()
            }
            Arrays.sort(fractions)
            g2.color = Color.GRAY // 设置边框色
            g2.fillRect(0, 0, w, h)
            val c: Color = getRandColor(200, 250)
            g2.color = c // 设置背景色
            g2.fillRect(0, 2, w, h - 4)
            //绘制干扰线
            val random = Random()
            g2.color = getRandColor(160, 200) // 设置线条的颜色
            for (i in 0..19) {
                val x: Int = random.nextInt(w - 1)
                val y: Int = random.nextInt(h - 1)
                val xl: Int = random.nextInt(6) + 1
                val yl: Int = random.nextInt(12) + 1
                g2.drawLine(x, y, x + xl + 40, y + yl + 20)
            }
            // 添加噪点
            val yawpRate = 0.05f // 噪声率
            val area = (yawpRate * w * h).toInt()
            for (i in 0 until area) {
                val x: Int = random.nextInt(w)
                val y: Int = random.nextInt(h)
                val rgb = randomIntColor
                image.setRGB(x, y, rgb)
            }
            shear(g2, w, h, c) // 使图片扭曲
            g2.color = getRandColor(100, 160)
            val fontSize = h - 4
            val font = Font("Algerian", Font.ITALIC, fontSize)
            g2.font = font
            val chars = code.toCharArray()
            for (i in 0 until verifySize) {
                val affine = AffineTransform()
                affine.setToRotation(Math.PI / 4 * rand.nextDouble() * if (rand.nextBoolean()) 1 else -1, w / verifySize * i + fontSize / 2.toDouble(), h / 2.toDouble())
                g2.transform = affine
                g2.drawChars(chars, i, 1, (w - 10) / verifySize * i + 5, h / 2 + fontSize / 2 - 10)
            }
            g2.dispose()
            ImageIO.write(image, "jpg", os)
        }
    
        private fun getRandColor(frontColor: Int, backgroundColor: Int): Color {
            var fc = frontColor
            var bc = backgroundColor
            if (fc > 255) fc = 255
            if (bc > 255) bc = 255
            val r: Int = fc + random.nextInt(bc - fc)
            val g: Int = fc + random.nextInt(bc - fc)
            val b: Int = fc + random.nextInt(bc - fc)
            return Color(r, g, b)
        }
    
        private val randomIntColor: Int
            get() {
                val rgb = randomRgb
                var color = 0
                for (c in rgb) {
                    color = color shl 8
                    color = color or c
                }
                return color
            }
    
        private val randomRgb: IntArray
            get() {
                val rgb = IntArray(3)
                for (i in 0..2) {
                    rgb[i] = random.nextInt(255)
                }
                return rgb
            }
    
        private fun shear(g: Graphics, w1: Int, h1: Int, color: Color) {
            shearX(g, w1, h1, color)
            shearY(g, w1, h1, color)
        }
    
        private fun shearX(g: Graphics, w1: Int, h1: Int, color: Color) {
            val period: Int = random.nextInt(2)
            val borderGap = true
            val frames = 1
            val phase: Int = random.nextInt(2)
            for (i in 0 until h1) {
                val d = ((period shr 1).toDouble()
                        * Math.sin(i.toDouble() / period.toDouble()
                        + 6.2831853071795862 * phase.toDouble()
                        / frames.toDouble()))
                g.copyArea(0, i, w1, 1, d.toInt(), 0)
                if (borderGap) {
                    g.setColor(color)
                    g.drawLine(d.toInt(), i, 0, i)
                    g.drawLine(d.toInt() + w1, i, w1, i)
                }
            }
        }
    
        private fun shearY(g: Graphics, w1: Int, h1: Int, color: Color) {
            val period: Int = random.nextInt(40) + 10 // 50;
            val borderGap = true
            val frames = 20
            val phase = 7
            for (i in 0 until w1) {
                val d = ((period shr 1).toDouble()
                        * Math.sin(i.toDouble() / period.toDouble()
                        + 6.2831853071795862 * phase.toDouble()
                        / frames.toDouble()))
                g.copyArea(i, 0, 1, h1, 0, d.toInt())
                if (borderGap) {
                    g.setColor(color)
                    g.drawLine(i, d.toInt(), i, 0)
                    g.drawLine(i, d.toInt() + h1, i, h1)
                }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:spring项目结构设计-验证码工具类

        本文链接:https://www.haomeiwen.com/subject/lykonhtx.html