Récemment, les codes de vérification coulissants sont progressivement devenus populaires sur de nombreux sites Web. D'une part, il est relativement nouveau pour l'expérience utilisateur et simple à utiliser. D'un autre côté, la sécurité n'a pas été considérablement réduite par rapport aux codes de vérification graphique. Bien sûr, jusqu'à présent, il n'y a pas de vérification de sécurité absolue, mais cela augmente simplement le coût du contournement pour les attaquants.
Ensuite, analysez le processus central du code de vérification coulissant:
Génère de manière aléatoire des découpes et des images d'arrière-plan avec des ombres de découpe sur le backend et enregistre des coordonnées de position de découpe aléatoire en arrière-plan.
Le front-end réalise l'interaction coulissante, met la découpe sur l'ombre de découpe et obtient la valeur de distance coulissante de l'utilisateur, comme l'exemple suivant
Le frontal passe la valeur de distance coulissante de l'utilisateur dans le back-end, et le back-end vérifie si l'erreur se trouve dans la plage admissible.
Ici, la vérification simplement de la distance de glissement de l'utilisateur est la vérification la plus élémentaire. Pour des raisons de sécurité plus élevées, toute la trajectoire du glissement de l'utilisateur, le comportement d'accès de l'utilisateur sur la page actuelle, etc. peut également être envisagé. Ceux-ci peuvent être complexes, et même à l'aide de modèles d'analyse des données du comportement des utilisateurs, l'objectif ultime est d'augmenter la difficulté de la simulation et du contournement illégales. Ce sont les opportunités qui peuvent être résumées et résumer des méthodes couramment utilisées. Cet article se concentre sur la façon de générer des codes de vérification de glissement étape par étape basé sur Java.
On peut voir que le code de vérification graphique coulissant se compose de deux images importantes, de la coupe de bloc et de l'image d'origine avec l'ombre de coupe de bloc. Il y a deux caractéristiques importantes ici pour assurer la difficulté d'être forcé par la brute: la forme de la coupe du bloc et la position de l'image d'origine où se trouve le bloc est aléatoire. Cela permet de créer des paires de découpes et d'images originales aléatoires et irrégulières dans un ensemble limité d'images.
Comment utiliser le code pour extraire une petite image avec une forme aléatoire spécifique à partir d'une grande image?
La première étape consiste à déterminer le contour de l'image de découpe pour faciliter l'exécution réelle de l'opération de traitement d'image à l'avenir.
L'image est composée de pixels et chaque point de pixels correspond à une couleur. La couleur peut être représentée sous forme RVB, plus une transparence, et comprendre une image comme une figure d'avion, avec le coin supérieur gauche comme l'origine, à l'axe x droit, et à l'axe Y en bas, une valeur de coordonnée correspond à la couleur du point de pixel à la position correspondante, de sorte qu'une image peut être convertie en une couleur de pixel à la position correspondante. Sur la base de cette considération, le contour est également représenté par un tableau bidimensionnel, la valeur de l'élément à l'intérieur du contour étant 1, et la valeur de l'élément en dehors du contour étant 0.
Pour le moment, vous devez réfléchir à la façon de générer cette forme de contour. Il existe des systèmes de coordonnées, des rectangles et des cercles. Oui, des fonctions graphiques mathématiques sont utilisées. En règle générale, les fonctions utilisant l'équation de fonction d'un cercle et la fonction de ligne latérale d'un rectangle, similaire à:
Dans (xa) ² + (yb) ² = r², il y a trois paramètres a, b et r, c'est-à-dire que la coordonnée centrale est (a, b) et le rayon r. Ces découpes sont placées sur le système de coordonnées décrit ci-dessus et il est facile de calculer les valeurs spécifiques du graphique.
L'exemple de code est le suivant:
private int [] [] getBlockData () {int [] [] data = new int [targetLength] [TargetWidth]; Double x2 = TargetLength-Circler-2; // la position du cercle généré au hasard double h1 = circler + math.random () * (TargetWidth-3 * circler-r1); double po = circler * circler; Double Xbegin = TargetLength-Circler-R1; double ybegin = cibleWidth-Circler-R1; for (int i = 0; i <cibleLength; i ++) {for (int j = 0; j <targetwidth; j ++) {// droit ○ 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; }La deuxième étape est qu'après ce contour, vous pouvez déterminer la découpe en fonction de la valeur de ce tableau bidimensionnel et ajouter une ombre à la position de découpe sur l'image d'origine.
L'opération est la suivante:
private void cutByTemplate (BufferedImage OriImage, BufferedImage TargetImage, int [] [] templateImage, int x, int y) {for (int i = 0; i <cibleLength; i ++) {for (int j = 0; j <ciblewidth; j ++) {int rgb = templateImage [i] [j]; // Le processus de décoloration des couleurs dans la position correspondante dans l'image d'origine int rgb_ori = oriimage.getrgb (x + i, y + j); if (rgb == 1) {// Copiez la valeur de couleur correspondante sur l'image de découpe cibleMage.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); // le changement de couleur de la position correspondante de l'image originale oriimage.setrgb (x + i, y + j, rgb_ori); }}}}Après les deux premières étapes, vous obtiendrez la découpe et l'image d'origine avec l'ombre découpée. Afin d'augmenter la confusion et d'améliorer l'effet de chargement du réseau, un traitement ultérieur des images est également nécessaire. Généralement, il y a deux choses à faire. L'un consiste à brouiller l'image et à augmenter la difficulté de reconnaissance de la machine, et l'autre consiste à effectuer une compression appropriée de la même qualité. Le traitement flou est facile à penser au flou gaussien, et le principe est facile à comprendre. Vous pouvez aller sur Google pour en savoir plus. Plus précisément pour la mise en œuvre de Java, il existe de nombreuses versions. Maintenant, il n'y a pas de pots tiers pour fournir un exemple:
Public Static Convolveop getGaussianBlurfilter (int radius, booléen horizontal) {if (rayon <1) {lance un nouveau IllégalArgumentException ("le rayon doit être> = 1"); } int size = rayon * 2 + 1; float [] data = new float [size]; float sigma = rayon / 3.0f; float twosigmasquare = 2.0f * Sigma * Sigma; float sigmaroot = (float) math.sqrt (twosigmasquare * math.pi); Float total = 0,0f; pour (int i = -radius; i <= rayon; i ++) {float Distance = i * i; int index = i + rayon; data [index] = (float) math.exp (-Distance / TwoSigmasquare) / Sigmaroot; Total + = données [index]; } pour (int i = 0; i <data.length; i ++) {data [i] / = total; } Kernel Kernel = null; if (horizontal) {kernel = nouveau noyau (taille, 1, données); } else {kernel = nouveau noyau (1, taille, données); } return new ConvolveOP (noyau, convolveop.edge_no_op, null); } public static void SimpleBlur (BufferedImage Src, BufferedImage dest) {BufferedImageOp Op = GetGauSsianBlurFilter (2, false); op.filter (Src, dest); }L'effet flou était très bon après les tests. De plus, c'est une compression d'image et aucun outil tiers n'est utilisé pour effectuer une compression homogène.
octet statique public [] FromBluffeReDImage2 (BufferedImage IMG, String ImageType) lève IOException {bos.Reset (); // Obtenez l'écrivain Iterator <ImageWriter> iter = imageo.getImageWritersByFormatName (Imagtype); ImageWriter Writer = (imagewriter) iter.Next (); // Obtenez les paramètres des paramètres de sortie de l'écrivain spécifié (imagewriteParam) imagewriteParam iwp = writer.getDefaultWriteParam (); iwp.setCompressionMode (imagewriteParam.mode_explicite); // Définissez s'il faut compresser iwp.setCompressionquality (1f); // Définir les paramètres de qualité de compression iwp.setProgressIVEMode (imagewriteParam.mode_disabled); ColorModel Colormodel = ColorModel.getrgBDefault (); // Spécifiez le mode de couleur utilisé pendant la compression iwp.setDestinationType (new Javax.imageio.imagetypeSpecificier (Colormodel, Colormodel.CreateCompatiblesAmpleModel (16, 16))); writer.setOutput (ImageIo .CreateImageOutputStream (BOS)); IioImage iiamge = new iioImage (img, null, null); écrivain.write (null, iiamge, iwp); octet [] d = bos.toByTearray (); retour d; }À ce stade, le processus de traitement du code du cœur du code de vérification coulissant a été terminé. Il existe de nombreux détails qui peuvent être polis et optimisés en permanence, afin que l'expérience de glissement puisse être meilleure. J'espère que cela peut aider certains étudiants qui se préparent à construire leur propre code de vérification coulissant.
Les implémentations de code ci-dessus sont très raffinées. D'une part, afin d'assurer les performances, et d'autre part, il est facile à comprendre. De plus, pour diverses raisons, il n'est pas pratique d'introduire trop de détails. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Après test, le temps de réponse du processus de la génération de graphiques coulissants peut être contrôlé à environ 20 ms. Si la résolution d'image d'origine est inférieure à 300px * 150px, elle peut atteindre environ 10 ms, ce qui se situe dans une plage acceptable. S'il existe un moyen plus efficace, j'espère me donner quelques conseils. J'espère également que tout le monde soutiendra davantage Wulin.com.