في الآونة الأخيرة ، أصبحت رموز التحقق المنزلق تدريجياً شائعة على العديد من مواقع الويب. من ناحية ، من الجديد نسبياً تجربة المستخدم وبسيطة التشغيل. من ناحية أخرى ، لم يتم تقليل الأمن بشكل كبير مقارنة برموز التحقق من الرسوم. بالطبع ، حتى الآن ، لا يوجد التحقق من الأمن المطلق ، لكنه يزيد من تكلفة الالتفافية للمهاجمين.
بعد ذلك ، قم بتحليل العملية الأساسية لرمز التحقق المنزلق:
يولد بشكل عشوائي قواطع وصور الخلفية مع ظلال قطع على الواجهة الخلفية ، ويحفظ إحداثيات وضع القطع العشوائية في الخلفية.
يدرك الواجهة الأمامية التفاعل المنزلق ، ويضع القطع على ظل القطع ، ويحصل على قيمة المسافة المنزلق للمستخدم ، مثل المثال التالي
يمر الواجهة الأمامية قيمة المسافة المنزلق للمستخدم في الواجهة الخلفية ، ويتحقق الواجهة الخلفية مما إذا كان الخطأ ضمن النطاق المسموح به.
هنا ، ببساطة التحقق من مسافة انزلاق المستخدم هو التحقق الأساسي. لأسباب أمنية أعلى ، يمكن أيضًا النظر في مسار انزلاق المستخدم بالكامل ، وسلوك الوصول إلى المستخدم على الصفحة الحالية ، وما إلى ذلك. يمكن أن تكون هذه معقدة ، وحتى بمساعدة نماذج تحليل بيانات سلوك المستخدم ، فإن الهدف النهائي هو زيادة صعوبة المحاكاة غير القانونية والتجاوز. هذه هي الفرص التي يمكن تلخيصها وتلخيصها طرق شائعة الاستخدام. تركز هذه المقالة على كيفية إنشاء رموز التحقق المنزلق خطوة بخطوة بناءً على Java.
يمكن ملاحظة أن رمز التحقق من الرسوم المنزلق يتكون من صورتين مهمتين ، قطع الكتلة والصورة الأصلية مع ظل قطع الكتلة. هناك ميزتان مهمتان هنا لضمان صعوبة التعرض للغشاش: شكل قطع الكتلة وموضع الصورة الأصلية حيث توجد الكتلة عشوائية. هذا يسمح بإنشاء أزواج عشوائية غير منتظمة من القواطع والصور الأصلية في مجموعة محدودة من الصور.
كيفية استخدام التعليمات البرمجية لاستخراج صورة صغيرة ذات شكل عشوائي محدد من صورة كبيرة؟
تتمثل الخطوة الأولى في تحديد الخطوط العريضة لصورة قطع لتسهيل التنفيذ الفعلي لعملية معالجة الصور في المستقبل.
تتكون الصورة من وحدات البكسل ، وتتوافق كل نقطة بكسل مع اللون. يمكن تمثيل اللون في شكل RGB ، بالإضافة إلى الشفافية ، وفهم صورة كشخصية طائرة ، مع الزاوية العلوية اليسرى كأصل ، إلى المحور السيني الأيمن ، وإلى المحور الأصلي ، تتوافق قيمة الإحداثي مع لون نقطة بكسل في الموضع المقابل ، بحيث يمكن تحويل الصورة إلى مسند ثنائي الأطوار. استنادًا إلى هذا الاعتبار ، يتم تمثيل المخطط التفصيلي أيضًا بمصفوفة ثنائية الأبعاد ، حيث تكون قيمة العنصر داخل المخطط التفصيلي 1 ، وقيمة العنصر خارج المخطط التفصيلي 0.
في هذا الوقت ، عليك أن تفكر في كيفية إنشاء هذا الشكل التفصيلي. هناك أنظمة الإحداثيات ، المستطيلات ، والدوائر. نعم ، يتم استخدام وظائف رسومية رياضية. عادةً ما تكون الوظائف باستخدام معادلة دالة الدائرة ووظيفة الخط الجانبي للمستطيل ، على غرار:
في (xa) ²+(yb) ² = r² ، هناك ثلاث معلمات a و b و r ، أي أن الإحداثيات المركزية هي (a ، b) ونصف قطرها r. يتم وضع هذه القواطع على نظام الإحداثيات الموضح أعلاه ومن السهل حساب القيم المحددة من الرسم البياني.
رمز العينة كما يلي:
private int [] [] getBlockData () {int [] [] data = new int [targetLength] [targetWidth] ؛ double x2 = targetlength-circler-2 ؛ . po double = circler*circler ؛ Double Xbegin = TargetLength-Circler-R1 ؛ ybegin double = TargetWidth-Circler-R1 ؛ لـ (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 ؛ } آخر {data [i] [j] = 1 ؛ }}} إرجاع بيانات ؛ }والخطوة الثانية هي أنه بعد هذا المخطط التفصيلي ، يمكنك تحديد الانقطاع بناءً على قيمة هذه المجموعة ثنائية الأبعاد وإضافة ظل إلى موضع القطع على الصورة الأصلية.
العملية كما يلي:
private void cutbytemplate (bufferedimage oriimage ، targetimage bufferedImage ، int [] [] templateimage ، int x ، int y) {for (int i = 0 ؛ i <targetlength ؛ i ++) {for (int j = 0 ؛ j <targetwidth ؛ j ++) {int rgb = tamplateimage [i] // عملية تلون اللون في الموضع المقابل في الصورة الأصلية int rgb_ori = oriimage.getrgb (x + i ، y + j) ؛ if (rgb == 1) {// انسخ قيمة اللون المقابلة على صورة cutout targetImage.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.setrgb (x + i ، y + j ، rgb_ori) ؛ }}}}بعد الخطوتين الأوليين ، ستحصل على القطع والصورة الأصلية مع Shadout Shadow. من أجل زيادة الارتباك وتحسين تأثير تحميل الشبكة ، هناك حاجة أيضًا إلى مزيد من معالجة الصور. بشكل عام ، هناك شيئان للقيام به. أحدهما هو طمس الصورة وزيادة صعوبة التعرف على الجهاز ، والآخر هو إجراء ضغط مناسب لنفس الجودة. من السهل التفكير في المعالجة الغامضة في الغموض الغاوسي ، والمبدأ سهل الفهم. يمكنك الذهاب إلى Google لمعرفة ذلك. على وجه التحديد لتنفيذ Java ، هناك العديد من الإصدارات. الآن ، لا توجد مرطبات تابعة لجهة خارجية لتقديم مثال:
includeop getGaussianBluRfilter العامة (دائرة نصف قطرها int ، أفقية منطقية) {if (radius <1) {رمي جديد alfictalargumentexception ("يجب أن يكون نصف القطر> = 1") ؛ } int size = نصف قطر * 2 + 1 ؛ تعويم [] بيانات = تعويم جديد [الحجم] ؛ تعويم sigma = نصف القطر / 3.0F ؛ float twosigmasquare = 2.0f * sigma * sigma ؛ float sigmaroot = (float) math.sqrt (twosigmasquare * math.pi) ؛ إجمالي تعويم = 0.0F ؛ لـ (int i = -radius ؛ i <= radius ؛ i ++) {float distant = i * i ؛ int index = i + radius ؛ البيانات [الفهرس] = (تعويم) Math.exp (-distance / twosigmasquare) / sigmaroot ؛ المجموع += البيانات [الفهرس] ؛ } لـ (int i = 0 ؛ i <data.length ؛ i ++) {data [i] /= total ؛ } kernel kernel = null ؛ if (أفقي) {kernel = new kernel (الحجم ، 1 ، البيانات) ؛ } آخر {kernel = new kernel (1 ، الحجم ، البيانات) ؛ } إرجاع New InvonveOp (kernel ، involveop.edge_no_op ، null) ؛ } public static void simpleblur (BufferedImage SRC ، bufferedimage dest) {bufferedImageOp op = getGaussianBlurfilter (2 ، false) ؛ OP.Filter (SRC ، Dest) ؛ }كان التأثير غير الواضح جيدًا بعد الاختبار. بالإضافة إلى ذلك ، فهو ضغط للصور ، ولا يتم استخدام أدوات الطرف الثالث لإجراء ضغط متجانس.
البايت الثابت العام [] fromBufferedImage2 (BufferEdImage IMG ، String ImageType) يلقي ioException {bos.reset () ؛ // احصل على الكاتب iterator <IcmageWriter> iter = imageio.getImageWritersByFormatName (imagtype) ؛ ImageWriter Writer = (ImageWriter) iter.next () ؛ // احصل على إعدادات معلمة الإخراج للكاتب المحدد (ImageWriteParam) ImageWriteParam iwp = constr.getDefaultWriteParam () ؛ iwp.setCompressionMode (ImageWriteParam.mode_explicit) ؛ // تعيين ما إذا كان يجب ضغط iwp.setCompressionFression (1F) ؛ . colormodel colormodel = colormodel.getRgbDefault () ؛ // حدد وضع اللون المستخدم أثناء الضغط iwp.setDestinationType (new javax.imageio.imagetypespespecifier (colormodel ، colormodel.createCophippatiblemplemodel (16 ، 16))) ؛ constr.setoutput (imageio. createImageOutputStream (BOS)) ؛ iioimage iiamge = new iioimage (img ، null ، null) ؛ Writer.write (null ، iiamge ، iwp) ؛ byte [] d = bos.tobytearray () ؛ العودة د ؛ }في هذه المرحلة ، تم الانتهاء من عملية معالجة التعليمات البرمجية في جوهر رمز التحقق المنزلق. هناك العديد من التفاصيل التي يمكن أن تكون مصقولة ومحسّنة بشكل مستمر ، بحيث يمكن أن تكون التجربة المنزلق أفضل. آمل أن يساعد بعض الطلاب الذين يستعدون لبناء رمز التحقق المنزلق الخاص بهم.
يتم تحسين تطبيقات الكود أعلاه. من ناحية ، من أجل ضمان الأداء ، ومن ناحية أخرى ، من السهل الفهم. بالإضافة إلى ذلك ، لأسباب مختلفة ، ليس من المناسب تقديم الكثير من التفاصيل. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل. بعد الاختبار ، يمكن التحكم في وقت استجابة العملية لتوليد الرسومات المنزلق في حوالي 20 مللي ثانية. إذا كانت دقة الصورة الأصلية أقل من 300px*150px ، فيمكن أن تصل إلى حوالي 10 مللي ثانية ، والتي تقع ضمن نطاق مقبول. إذا كانت هناك طريقة أكثر كفاءة ، آمل أن أقدم لي بعض النصائح. آمل أيضًا أن يدعم الجميع wulin.com أكثر.