网友写的验证码生成方案,可防止绝大多数机械识别。_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 网友写的验证码生成方案,可防止绝大多数机械识别。

网友写的验证码生成方案,可防止绝大多数机械识别。

 2014/11/25 11:52:25  技术狂  程序员俱乐部  我要评论(0)
  • 摘要:web.xmlXml代码<!DOCTYPEweb-appPUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!--********************************************--><!-
  • 标签:
web.xmlclass="Apple-converted-space">  Xml代码 javascripts/syntaxhighlighter/clipboard_new.swf" type="application/x-shockwave-flash">systems%2C%20Inc.%2F%2FDTD%20Web%20Application%202.3%2F%2FEN%22%0A%20%22http%3A%2F%2Fjava.sun.com%2Fdtd%2Fweb-app_2_3.dtd%22%20%3E%0A%0A%3Cweb-app%3E%0A%09%3C!--%20********************************************%20--%3E%0A%09%3C!--%20**********%E9%AA%8C%E8%AF%81%E7%A0%81%E7%94%9F%E6%88%90%E5%99%A8**************************%20--%3E%0A%09%3C!--%20********************************************%20--%3E%0A%09%3Cservlet%3E%0A%09%09%3Cservlet-name%3ECaptchaServlet%3C%2Fservlet-name%3E%0A%09%09%3Cservlet-class%3Ecom.lowca.activity.web.servlet.CaptchaServlet%3C%2Fservlet-class%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3Ewidth%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E150%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3Eheight%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E100%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EbgColor%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E255%2C255%2C255%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EfontColor%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E0%2C255%2C0%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EfontSize%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E44%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EfontCount%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E4%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EfontName%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E%E5%AE%8B%E4%BD%93%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3Echars%3C%2Fparam-name%3E%0A%09%09%09%3C!--%20%E5%8E%BB%E6%8E%89%E4%BA%86%E5%AE%B9%E6%98%93%E9%80%A0%E6%88%90%E8%AF%AF%E8%A7%A3%E7%9A%84%E5%AD%97%E7%AC%A6%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9Ai%20o%20z%20%E5%92%8C%201%200%202%20--%3E%0A%09%09%09%3Cparam-value%3EABCDEFGHJKLMNPQRSTUVWXYabcdefghjkmnpqrstuvwxy3456789%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EsessionKey%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3Ecom.lowca.activity.captcha%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EmaxRotateAngle%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E40%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%09%3Cinit-param%3E%0A%09%09%09%3Cparam-name%3EfontPadding%3C%2Fparam-name%3E%0A%09%09%09%3Cparam-value%3E-15%3C%2Fparam-value%3E%0A%09%09%3C%2Finit-param%3E%0A%09%3C%2Fservlet%3E%0A%0A%09%3Cservlet-mapping%3E%0A%09%09%3Cservlet-name%3ECaptchaServlet%3C%2Fservlet-name%3E%0A%09%09%3Curl-pattern%3E%2Fcaptcha.jpg%3C%2Furl-pattern%3E%0A%09%3C%2Fservlet-mapping%3E%0A%3C%2Fweb-app%3E%0A" />ways" /> 收藏代码
  1. <!DOCTYPE web-app PUBLIC  
  2.  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
  3.  "http://java.sun.com/dtd/web-app_2_3.dtd" >  
  4.   
  5. <web-app>  
  6.     <!-- ******************************************** -->  
  7.     <!-- **********验证码生成器************************** -->  
  8.     <!-- ******************************************** -->  
  9.     <servlet>  
  10.         <servlet-name>CaptchaServlet</servlet-name>  
  11.         <servlet-class>com.lowca.activity.web.servlet.CaptchaServlet</servlet-class>  
  12.         <init-param>  
  13.             <param-name>width</param-name>  
  14.             <param-value>150</param-value>  
  15.         </init-param>  
  16.         <init-param>  
  17.             <param-name>height</param-name>  
  18.             <param-value>100</param-value>  
  19.         </init-param>  
  20.         <init-param>  
  21.             <param-name>bgColor</param-name>  
  22.             <param-value>255,255,255</param-value>  
  23.         </init-param>  
  24.         <init-param>  
  25.             <param-name>fontColor</param-name>  
  26.             <param-value>0,255,0</param-value>  
  27.         </init-param>  
  28.         <init-param>  
  29.             <param-name>fontSize</param-name>  
  30.             <param-value>44</param-value>  
  31.         </init-param>  
  32.         <init-param>  
  33.             <param-name>fontCount</param-name>  
  34.             <param-value>4</param-value>  
  35.         </init-param>  
  36.         <init-param>  
  37.             <param-name>fontName</param-name>  
  38.             <param-value>宋体</param-value>  
  39.         </init-param>  
  40.         <init-param>  
  41.             <param-name>chars</param-name>  
  42.             <!-- 去掉了容易造成误解的字符,例如:i o z 和 1 0 2 -->  
  43.             <param-value>ABCDEFGHJKLMNPQRSTUVWXYabcdefghjkmnpqrstuvwxy3456789</param-value>  
  44.         </init-param>  
  45.         <init-param>  
  46.             <param-name>sessionKey</param-name>  
  47.             <param-value>com.lowca.activity.captcha</param-value>  
  48.         </init-param>  
  49.         <init-param>  
  50.             <param-name>maxRotateAngle</param-name>  
  51.             <param-value>40</param-value>  
  52.         </init-param>  
  53.         <init-param>  
  54.             <param-name>fontPadding</param-name>  
  55.             <param-value>-15</param-value>  
  56.         </init-param>  
  57.     </servlet>  
  58.   
  59.     <servlet-mapping>  
  60.         <servlet-name>CaptchaServlet</servlet-name>  
  61.         <url-pattern>/captcha.jpg</url-pattern>  
  62.     </servlet-mapping>  
  63. </web-app>  
servlet类文件  Java代码 rotate(angle%2C%20x%2C%20offsetY)%3B%0A%09%09%09g2d.setTransform(newXform)%3B%0A%09%09%09g2d.drawString(word%2C%20x%2C%20offsetY)%3B%0A%09%09%09g2d.setTransform(origXform)%3B%0A%09%09%7D%0A%09%09g2d.setStroke(new%20BasicStroke(2.0f))%3B%0A%09%09int%20x%20%3D%20offsetX%20-%20(int)%20(20%20*%20Math.random())%3B%0A%09%09int%20y%20%3D%20offsetY%20-%20(int)%20(20%20*%20Math.random())%3B%0A%09%09int%20w%20%3D%20(int)%20(width%20-%2010%20-%20Math.random()%20*%206)%3B%0A%09%09int%20h%20%3D%20(int)%20(height%20-%2010%20-%20Math.random()%20*%206)%3B%0A%09%09int%20startAngle%20%3D%20(int)%20(Math.random()%20*%2016%20%2B%2045)%3B%0A%09%09int%20arcAngle%20%3D%20(int)%20(Math.random()%20*%2045%20%2B%2090)%3B%0A%09%09g2d.drawArc(x%2C%20y%2C%20w%2C%20h%2C%20startAngle%2C%20arcAngle)%3B%0A%09%09g2d.dispose()%3B%0A%0A%09%09%2F%2F%20%E5%B0%86%E5%9B%9B%E4%BD%8D%E6%95%B0%E5%AD%97%E7%9A%84%E9%AA%8C%E8%AF%81%E7%A0%81%E4%BF%9D%E5%AD%98%E5%88%B0Session%E9%87%8C%E9%9D%A2%0A%09%09HttpSession%20session%20%3D%20req.getSession()%3B%0A%09%09session.setAttribute(sessionKey%2C%20randCode)%3B%0A%0A%09%09%2F%2F%20%E7%A6%81%E6%AD%A2%E5%9B%BE%E5%83%8F%E7%BC%93%E5%AD%98%0A%09%09resp.setHeader(%22Prama%22%2C%20%22no-cache%22)%3B%0A%09%09resp.setHeader(%22Coche-Control%22%2C%20%22no-cache%22)%3B%0A%09%09resp.setDateHeader(%22Expires%22%2C%200)%3B%0A%0A%09%09%2F%2F%20%E5%B0%86%E5%9B%BE%E5%83%8F%E8%BE%93%E5%87%BA%E5%88%B0Servelt%E8%BE%93%E5%87%BA%E6%B5%81%E4%B8%AD%0A%09%09ServletOutputStream%20out%20%3D%20resp.getOutputStream()%3B%0A%09%09ImageIO.write(buffImg%2C%20%22jpeg%22%2C%20out)%3B%0A%09%09out.close()%3B%0A%09%7D%0A%0A%09public%20void%20doPost(HttpServletRequest%20request%2C%20HttpServletResponse%20response)%0A%09%09%09throws%20ServletException%2C%20IOException%20%7B%0A%09%09doGet(request%2C%20response)%3B%0A%09%7D%0A%0A%09public%20void%20doGet(HttpServletRequest%20request%2C%20HttpServletResponse%20response)%0A%09%09%09throws%20ServletException%2C%20IOException%20%7B%0A%09%09response.setContentType(CONTENT_TYPE)%3B%0A%09%7D%0A%0A%09public%20void%20init()%20throws%20ServletException%20%7B%0A%09%09%2F%2F%20%E5%88%9D%E5%A7%8B%E5%8C%96%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0%0A%09%09String%20param%20%3D%20getInitParameter(%22width%22)%3B%0A%09%09if%20(NumberUtils.isDigits(param))%20%7B%0A%09%09%09width%20%3D%20Integer.parseInt(param)%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22height%22)%3B%0A%09%09if%20(NumberUtils.isDigits(param))%20%7B%0A%09%09%09height%20%3D%20Integer.parseInt(param)%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22bgColor%22)%3B%0A%09%09if%20(param%20!%3D%20null%20%26%26%20param.matches(%22%5E%5C%5Cd%2B%2C%5C%5Cd%2B%2C%5C%5Cd%2B%24%22))%20%7B%0A%09%09%09bgColor%20%3D%20getColor(param)%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22fontColor%22)%3B%0A%09%09if%20(param%20!%3D%20null%20%26%26%20param.matches(%22%5E%5C%5Cd%2B%2C%5C%5Cd%2B%2C%5C%5Cd%2B%24%22))%20%7B%0A%09%09%09fontColor%20%3D%20getColor(param)%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22fontSize%22)%3B%0A%09%09if%20(NumberUtils.isDigits(param))%20%7B%0A%09%09%09fontSize%20%3D%20Integer.parseInt(param)%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22maxRotateAngle%22)%3B%0A%09%09if%20(NumberUtils.isDigits(param))%20%7B%0A%09%09%09maxRotateAngle%20%3D%20Integer.parseInt(param)%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22fontPadding%22)%3B%0A%09%09if%20(param%20!%3D%20null%20%26%26%20param.matches(%22-%3F%5C%5Cd%2B%22))%20%7B%0A%09%09%09fontPadding%20%3D%20Integer.parseInt(param)%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22fontName%22)%3B%0A%09%09if%20(StringUtils.isNotBlank(param))%20%7B%0A%09%09%09fontName%20%3D%20param%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22chars%22)%3B%0A%09%09if%20(StringUtils.isNotBlank(param))%20%7B%0A%09%09%09chars%20%3D%20param%3B%0A%09%09%7D%0A%09%09param%20%3D%20getInitParameter(%22sessionKey%22)%3B%0A%09%09if%20(StringUtils.isNotBlank(sessionKey))%20%7B%0A%09%09%09sessionKey%20%3D%20param%3B%0A%09%09%7D%0A%09%09%2F%2F%20%E5%88%9D%E5%A7%8B%E5%8C%96%E7%8A%B6%E6%80%81%E5%8F%98%E9%87%8F%0A%09%09font%20%3D%20new%20Font(fontName%2C%20Font.ITALIC%2C%20fontSize)%3B%0A%09%09seedArray%20%3D%20chars.toCharArray()%3B%0A%09%09offsetX%20%3D%20width%20%2F%202%20-%20fontCount%20*%20fontSize%20%2F%202%20-%20(fontCount%20-%201)%0A%09%09%09%09*%20fontPadding%20%2F%202%20-%208%3B%0A%09%09offsetY%20%3D%20height%20%2F%202%20%2B%20fontSize%20%2F%202%20-%208%3B%0A%09%7D%0A%0A%09private%20Color%20getColor(String%20rgb)%20%7B%0A%09%09String%5B%5D%20array%20%3D%20rgb.split(%22%2C%22)%3B%0A%09%09return%20new%20Color(Integer.parseInt(array%5B0%5D)%2C%0A%09%09%09%09Integer.parseInt(array%5B1%5D)%2C%20Integer.parseInt(array%5B2%5D))%3B%0A%09%7D%0A%0A%7D%0A" /> 收藏代码
  1. package com.lowca.activity.web.servlet;  
  2.   
  3. import java.awt.BasicStroke;  
  4. import java.awt.Color;  
  5. import java.awt.Font;  
  6. import java.awt.Graphics2D;  
  7. import java.awt.geom.AffineTransform;  
  8. import java.awt.image.BufferedImage;  
  9. import java.io.IOException;  
  10.   
  11. import javax.imageio.ImageIO;  
  12. import javax.servlet.ServletException;  
  13. import javax.servlet.ServletOutputStream;  
  14. import javax.servlet.http.HttpServlet;  
  15. import javax.servlet.http.HttpServletRequest;  
  16. import javax.servlet.http.HttpServletResponse;  
  17. import javax.servlet.http.HttpSession;  
  18.   
  19. import org.apache.commons.lang.StringUtils;  
  20. import org.apache.commons.lang.math.NumberUtils;  
  21.   
  22. public class CaptchaServlet extends HttpServlet {  
  23.   
  24.     private static final long serialVersionUID = 1L;  
  25.   
  26.     private static final String CONTENT_TYPE = "image/jpeg";  
  27.   
  28.     // ==================以下变量用于保存配置参数的默认值 ==================  
  29.     /** 
  30.      * 验证码的宽度 
  31.      */  
  32.     private int width = 200;  
  33.     /** 
  34.      * 验证码的高度 
  35.      */  
  36.     private int height = 150;  
  37.     /** 
  38.      * 验证码背景色 
  39.      */  
  40.     private Color bgColor = Color.WHITE;  
  41.     /** 
  42.      * 文字颜色 
  43.      */  
  44.     private Color fontColor = Color.GREEN;  
  45.     /** 
  46.      * 验证码字符字号 
  47.      */  
  48.     private int fontSize = 42;  
  49.     /** 
  50.      * 验证码字符个数 
  51.      */  
  52.     private int fontCount = 4;  
  53.     /** 
  54.      * 验证码字符间距,单位是像素 
  55.      */  
  56.     private int fontPadding = -15;  
  57.     /** 
  58.      * 验证码字符最大旋转角度 
  59.      */  
  60.     private int maxRotateAngle = 40;  
  61.     /** 
  62.      * 验证码字体 
  63.      */  
  64.     private String fontName = "宋体";  
  65.     /** 
  66.      * 验证码用到的字符 
  67.      */  
  68.     private String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  
  69.     /** 
  70.      * 验证码在session中的键名 
  71.      */  
  72.     private String sessionKey = "com.lowca.activity.captcha";  
  73.   
  74.     // ==================以下变量用于在初始化时候保存数据,减少重复计算 ==================  
  75.   
  76.     private Font font;  
  77.   
  78.     private char[] seedArray;  
  79.   
  80.     private int offsetX = 0;  
  81.   
  82.     private int offsetY = 0;  
  83.   
  84.     /** 
  85.      * 生成由数字和字母随机组成的图片 
  86.      */  
  87.     protected void service(HttpServletRequest req, HttpServletResponse resp)  
  88.             throws ServletException, java.io.IOException {  
  89.         BufferedImage buffImg = new BufferedImage(width, height,  
  90.                 BufferedImage.TYPE_INT_RGB);  
  91.         Graphics2D g2d = buffImg.createGraphics();  
  92.         g2d.setColor(bgColor);  
  93.         g2d.fillRect(0, 0, width, height);  
  94.         g2d.setPaint(fontColor);  
  95.         g2d.setFont(font);  
  96.         // 旋转文本  
  97.   
  98.         StringBuffer randCode = new StringBuffer();  
  99.         for (int i = 0; i < fontCount; i++) {  
  100.             g2d.setStroke(new BasicStroke((float) (Math.random() * 5)));  
  101.             double angle = Math.random() * maxRotateAngle * Math.PI / 180;  
  102.             int p = (int) (Math.random() * chars.length());  
  103.             String word = String.valueOf(seedArray[p]);  
  104.             randCode.append(word);  
  105.             int x = offsetX + i * (fontSize + fontPadding);  
  106.   
  107.             AffineTransform origXform = g2d.getTransform();  
  108.             AffineTransform newXform = (AffineTransform) (origXform.clone());  
  109.             newXform.rotate(angle, x, offsetY);  
  110.             g2d.setTransform(newXform);  
  111.             g2d.drawString(word, x, offsetY);  
  112.             g2d.setTransform(origXform);  
  113.         }  
  114.         g2d.setStroke(new BasicStroke(2.0f));  
  115.         int x = offsetX - (int) (20 * Math.random());  
  116.         int y = offsetY - (int) (20 * Math.random());  
  117.         int w = (int) (width - 10 - Math.random() * 6);  
  118.         int h = (int) (height - 10 - Math.random() * 6);  
  119.         int startAngle = (int) (Math.random() * 16 + 45);  
  120.         int arcAngle = (int) (Math.random() * 45 + 90);  
  121.         g2d.drawArc(x, y, w, h, startAngle, arcAngle);  
  122.         g2d.dispose();  
  123.   
  124.         // 将四位数字的验证码保存到Session里面  
  125.         HttpSession session = req.getSession();  
  126.         session.setAttribute(sessionKey, randCode);  
  127.   
  128.         // 禁止图像缓存  
  129.         resp.setHeader("Prama", "no-cache");  
  130.         resp.setHeader("Coche-Control", "no-cache");  
  131.         resp.setDateHeader("Expires", 0);  
  132.   
  133.         // 将图像输出到Servelt输出流中  
  134.         ServletOutputStream out = resp.getOutputStream();  
  135.         ImageIO.write(buffImg, "jpeg", out);  
  136.         out.close();  
  137.     }  
  138.   
  139.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  140.             throws ServletException, IOException {  
  141.         doGet(request, response);  
  142.     }  
  143.   
  144.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  145.             throws ServletException, IOException {  
  146.         response.setContentType(CONTENT_TYPE);  
  147.     }  
  148.   
  149.     public void init() throws ServletException {  
  150.         // 初始化配置参数  
  151.         String param = getInitParameter("width");  
  152.         if (NumberUtils.isDigits(param)) {  
  153.             width = Integer.parseInt(param);  
  154.         }  
  155.         param = getInitParameter("height");  
  156.         if (NumberUtils.isDigits(param)) {  
  157.             height = Integer.parseInt(param);  
  158.         }  
  159.         param = getInitParameter("bgColor");  
  160.         if (param != null && param.matches("^\\d+,\\d+,\\d+$")) {  
  161.             bgColor = getColor(param);  
  162.         }  
  163.         param = getInitParameter("fontColor");  
  164.         if (param != null && param.matches("^\\d+,\\d+,\\d+$")) {  
  165.             fontColor = getColor(param);  
  166.         }  
  167.         param = getInitParameter("fontSize");  
  168.         if (NumberUtils.isDigits(param)) {  
  169.             fontSize = Integer.parseInt(param);  
  170.         }  
  171.         param = getInitParameter("maxRotateAngle");  
  172.         if (NumberUtils.isDigits(param)) {  
  173.             maxRotateAngle = Integer.parseInt(param);  
  174.         }  
  175.         param = getInitParameter("fontPadding");  
  176.         if (param != null && param.matches("-?\\d+")) {  
  177.             fontPadding = Integer.parseInt(param);  
  178.         }  
  179.         param = getInitParameter("fontName");  
  180.         if (StringUtils.isNotBlank(param)) {  
  181.             fontName = param;  
  182.         }  
  183.         param = getInitParameter("chars");  
  184.         if (StringUtils.isNotBlank(param)) {  
  185.             chars = param;  
  186.         }  
  187.         param = getInitParameter("sessionKey");  
  188.         if (StringUtils.isNotBlank(sessionKey)) {  
  189.             sessionKey = param;  
  190.         }  
  191.         // 初始化状态变量  
  192.         font = new Font(fontName, Font.ITALIC, fontSize);  
  193.         seedArray = chars.toCharArray();  
  194.         offsetX = width / 2 - fontCount * fontSize / 2 - (fontCount - 1)  
  195.                 * fontPadding / 2 - 8;  
  196.         offsetY = height / 2 + fontSize / 2 - 8;  
  197.     }  
  198.   
  199.     private Color getColor(String rgb) {  
  200.         String[] array = rgb.split(",");  
  201.         return new Color(Integer.parseInt(array[0]),  
  202.                 Integer.parseInt(array[1]), Integer.parseInt(array[2]));  
  203.     }  
  204.   
  205. }  
在我的机器上,这个程序每秒钟可以产生大约83张验证码。验证码图样如下
  • 大小: 2.6 KB
  • 大小: 2.5 KB
  • 大小: 2.4 KB
  • 大小: 2.4 KB
  • 相关文章
发表评论
用户名: 匿名