Java sample code for sliding Verification Code
Recently, slide verification codes have gradually become popular in many websites. On the one hand, they are relatively novel and easy to operate for the user experience. On the other hand, compared with graphic verification codes, verification codes are not very secure. Of course, up to now, there has been no absolute security verification, but the costs of attackers are constantly increasing.
Next, we will analyze the core process of the sliding verification code:
The backend randomly generates a background image with a background image and a background image with a background shadow. The background stores the coordinates of the random position of the background image.
The front-end implements slide interaction, and puts the image on the shadow to obtain the user's sliding distance value, for example, the following example:
The frontend transmits the user's sliding distance value to the backend, and checks whether the backend verification error is within the permitted range.
Here, the verification of user sliding distance is the most basic verification. For higher security considerations, you may also consider the entire trajectory of user sliding and user access behavior on the current page. These can be complex. Even with the help of the user behavior data analysis model, the ultimate goal is to increase the difficulty of illegal simulation and bypass. This article focuses on how to generate a sliding Verification Code step by step based on Java.
As you can see, the slide graphic verification code is composed of two important pictures: The primary block and the source image with the hidden block shadow. There are two important features to ensure the difficulty of brute-force cracking: the shape of the primary block is random, and the position of the original image where the primary block is located is random. In this way, you can create random, irregular, and searchable matching of the source image in a limited Gallery.
How can I use code to extract a small image with a specific random shape from a large figure?
Step 1: first determine the outline of an image to facilitate subsequent operations on image processing.
An image consists of pixels. Each pixel corresponds to a color. The color can be expressed in RGB format, and a transparency is added. A picture is understood as a plane image. The top left corner is the origin, and the right X axis, down the Y axis, a coordinate value pair is the color of the pixel at the position, so that you can convert a graph into a two-dimensional array. Based on this consideration, the contour is also represented by a two-dimensional array. The element value inside the contour is 1, and the element value outside the contour corresponds to 0.
At this time, we need to think about how to generate the contour shape. There are coordinate systems, rectangles, and circles. That's right. Mathematical graphical functions are used. A typical use of a circular function equation and a function of the rectangular edge, similar:
(X-a) ² + (y-B) ² = r², there are three parameters a, B, r, that is, the Center Coordinate is (a, B ), radius r. These images are placed in the coordinate system described above, and the specific values of the images are easily calculated.
The sample code is as follows:
Private int [] [] getBlockData () {int [] [] data = new int [targetLength] [targetWidth]; double x2 = targetLength-circleR-2; // randomly generate the position of the circle. double h1 = circleR + Math. random () * (targetWidth-3 * circleR-r1); double po = circleR * circleR; double xbegin = targetLength-circleR-r1; double ybegin = targetWidth-circleR-r1; for (int I = 0; I <targetLength; I ++) {for (int j = 0; j <targetWidth; j ++) {// right ○ double d3 = Math. pow (I-x2, 2) + Math. pow (j-h1, 2); if (d1 <= po | (j> = ybegin & d2> = po) | (I >= xbegin & d3> = po) {data [I] [j] = 0 ;} else {data [I] [j] = 1 ;}} return data ;}
Step 2: With this contour, you can determine the image based on the value of the two-dimensional array and add a shadow at the position of the image.
The procedure is as follows:
Private void cutByTemplate (BufferedImage oriImage, BufferedImage targetImage, int [] [] templateImage, int x, int y) {for (int I = 0; I <targetLength; I ++) {for (int j = 0; j <targetWidth; j ++) {int rgb = templateImage [I] [j]; // color-changing processing int rgb_ori = oriImage in the source image. getRGB (x + I, y + j); if (rgb = 1) {// copy the corresponding color value targetImage on the image. setRGB (I, y + j, rgb_ori); int r = (0xff & rgb_ori); int g = (0xff & (rgb_ori> 8 )); int B = (0xff & (rgb_ori> 16); rgb_ori = r + (g <8) + (B <16) + (200 <24 ); // oriImage changes in color at the corresponding position of the source image. setRGB (x + I, y + j, rgb_ori );}}}}
After the previous two steps, you can obtain the source image with a thumbnail and a shadow. To increase obfuscation and improve network loading performance, further processing of images is required. Generally, two things need to be done. Fuzzy processing of a pair of images increases the difficulty of machine identification. Second, compress the same quality properly. Fuzzy processing is easy to think of Gaussian blur, and its principles are well understood. You can go to google to learn more. The implementation in Java involves many versions. An example is provided without any third-party jar:
public static ConvolveOp getGaussianBlurFilter(int radius, boolean horizontal) { if (radius < 1) { throw new IllegalArgumentException("Radius must be >= 1"); } int size = radius * 2 + 1; float[] data = new float[size]; float sigma = radius / 3.0f; float twoSigmaSquare = 2.0f * sigma * sigma; float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI); float total = 0.0f; for (int i = -radius; i <= radius; i++) { float distance = i * i; int index = i + radius; data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot; total += data[index]; } for (int i = 0; i < data.length; i++) { data[i] /= total; } Kernel kernel = null; if (horizontal) { kernel = new Kernel(size, 1, data); } else { kernel = new Kernel(1, size, data); } return new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); }public static void simpleBlur(BufferedImage src,BufferedImage dest) { BufferedImageOp op = getGaussianBlurFilter(2,false); op.filter(src, dest); }
After testing, the blur effect is very good. In addition, image compression does not use any third-party tools for homogeneous compression.
Public static byte [] fromBufferedImage2 (BufferedImage img, String imagType) throws IOException {bos. reset (); // get the writer Iterator <ImageWriter> iter = ImageIO for the specified Format image. getImageWritersByFormatName (imagType); ImageWriter writer = (ImageWriter) iter. next (); // get the output parameter settings of the specified writer (ImageWriteParam) ImageWriteParam iwp = writer. getDefaultWriteParam (); iwp. setCompressionMode (ImageWriteParam. MODE_EXPLICIT); // sets whether iwp can be compressed. setCompressionQuality (1f); // sets the compression quality parameter iwp. setProgressiveMode (ImageWriteParam. MODE_DISABLED); ColorModel colorModel = ColorModel. getRGBdefault (); // specifies the iwp color mode used for compression. setDestinationType (new javax. imageio. imageTypeSpecifier (colorModel, colorModel. createCompatibleSampleModel (16, 16); writer. setOutput (ImageIO. createImageOutputStream (bos); IIOImage iIamge = new IIOImage (img, null, null); writer. write (null, iIamge, iwp); byte [] d = bos. toByteArray (); return d ;}
At this point, the code processing process of the sliding Verification Code core has been completed. There are many details that can be constantly optimized to improve the sliding experience. Hope to help some students who are preparing to build their own slide verification codes.
The above code implementation is very refined. On the one hand, to ensure performance, on the other hand, it is easy to understand. In addition, too many details cannot be introduced due to various reasons. If you have any questions, leave a message. After testing, the process response time of the generated slide image can be controlled at around 20 ms. If the source image resolution is below PX * PX, it can be around 10 ms and within the acceptable range. If you have a more efficient method, I hope you can give me more advice. We also hope that you can support the customer's home.