一段java代码带你认识锟斤拷

@Test
public void testKunJinKao(){
  String str="我不是锟斤拷";
  try {
    byte[] buff=null;

    //让我们先看看几种错误的转换,let's go

    //1. 正常的GBK字节流,你以为是UTF-8,所以用UTF-8去解码...
    buff=str.getBytes("GBK");//这里只要不抛异常,数据一定不会被破坏
    String str1=new String(buff,"UTF-8");
    System.out.println(str1);//这是一种情形:���

    //2. 正常的UTF-8字节流,你以为是GBK,所以用GBK去解码...
    buff=str.getBytes("UTF-8");//这里只要不抛异常,数据一定不会被破坏
    String str2=new String(buff,"GBK");//这里破坏了
    System.out.println(str2);//这是另外一种情形:

    //说了半天,锟斤拷在哪里呢?come on

    //3. 本来正常的GBK字节码,在你不知道的某个环节已经被错误的使用UTF-8解码了
    String str3=new String(str.getBytes("GBK"),"UTF-8");
    String str4=new String(str3.getBytes("UTF-8"),"GBK");//这里你并不知道数据已经破坏了,这样用是对的。
    System.out.println(str4);//锟斤拷

    /**
     * Got it.How are you,nice to meet you.
     *
     * Why?
     * 如果说情形1、2是开发者自己造成的,
     * 那么情形3往往是开发者被坑了,别人造成的(也可能是容器层),总之你拿到的时候已经乱了。
     */

    /**
     * 细心的你会发现,正是情形1的错误,导致了情形3的发生。之所以表现不同,是因为情形1的程序猿是在UTF-8下打印输出;
     * 而情形3是在GBK下打印输出。
     */

    /**
     * 总结一下,锟斤拷是怎么产生的?
     *
     * 源于GBK字符集和Unicode字符集之间的转换问题。
     * Unicode和老编码体系的转化过程中,肯定有一些字,用Unicode是没法表示的,
     * Unicode官方用了一个占位符(REPLACEMENT CHARACTER)来表示这些文字,这就是:U+FFFD
     *
     * U+FFFD的UTF-8编码出来,恰好是 '\xef\xbf\xbd'。
     *
     * 重复多次,例如 '\xef\xbf\xbd\xef\xbf\xbd',
     * 然后放到GBK/CP936/GB2312/GB18030的环境中显示的话,
     * 一个汉字2个字节,最终的结果就是:锟斤拷——锟(0xEFBF),斤(0xBDEF),拷(0xBFBD)。
     */
  } catch (Exception e) {
    e.printStackTrace();
  }


}

转载于:https://my.oschina.net/polly/blog/890120

package Cls; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class MyVerifyCode extends HttpServlet { private static MyVerifyCode instance; private final String ATTRIBUTE_NAME = "verifycode"; // ��֤���ַ������� private final int CODE_LENGTH =4; // ��֤��߶����� private static final int Height =30; // ������֤���Ƿ���Ҫ��תЧ�� private boolean ROTATE_FLAG = true; //���������Ƿ���Ҫ��� private boolean FONT_FLAG=false; //�����������Ĭ������ private String font=""; //��������Ĵ�С,Ĭ��Ϊ15 private int fontsize=15; private final String RAND_RANGE = "abcdefhgkmnpqrstuvwxyz" + "ABCDEFGHGKLMNPQRSTUVWXYZ" + "2345678"; // private Random rand=new Random(); public static Random rand = new Random(); private final char[] CHARS = RAND_RANGE.toCharArray(); // ���캯�� public MyVerifyCode() { } public static MyVerifyCode getInstance() { if (instance == null) instance = new MyVerifyCode(); return instance; } // �������ַ� private String getRandString() { StringBuffer vcode = new StringBuffer(); for (int i = 0; i < CODE_LENGTH; i++) vcode.append(CHARS[rand.nextInt(CHARS.length)]); return vcode.toString(); } // ��������� public static float getRandomJiao() { float jiao = 0.0f; if (rand.nextFloat()<=0.5) { jiao = rand.nextFloat()-0.3f; } else { jiao = -rand.nextFloat()+0.3f; } return jiao; } // ��������ɫ private Color getRandColor(int ll, int ul) { if (ll > 255) ll = 255; if (ll < 1) ll = 1; if (ul > 255) ul = 255; if (ul < 1) ul = 1; if (ul == ll) ul = ll + 1; int r = rand.nextInt(ul - ll) + ll; int g = rand.nextInt(ul - ll) + ll; int b = rand.nextInt(ul - ll) + ll; Color color = new Color(r, g, b); return color; } private BufferedImage getImage(HttpServletRequest request) { //根据设置的高度计算事宜的fontsize int FontSize=Height*75/96; //根据设置的字体及字的个数计算出适宜的宽度 int width = CODE_LENGTH * FontSize*4/5 + 10; //根据字体大小设置X轴的位移量 int X_=FontSize/2; BufferedImage image = new BufferedImage(width,Height, BufferedImage.TYPE_INT_RGB); // ��ȡͼ�������� Graphics graphics = image.getGraphics(); Graphics2D g2 = (Graphics2D) graphics; g2.setColor(getRandColor(100, 255)); g2.setColor(Color.WHITE); g2.fillRect(0, 0, width, Height); g2.translate(0, Height*2/3); double oldrot = 0; String vcode=this.getRandString(); // 把验证码存入session request.getSession(true).setAttribute("codes", vcode); for (int i = 0; i < CODE_LENGTH; i++) { g2.setFont(new Font("Times New Roman", Font.HANGING_BASELINE, FontSize)); double rot = getRandomJiao(); // 旋转画笔 if (ROTATE_FLAG) { g2.rotate(-oldrot); g2.translate(X_+rand.nextInt(8), 0); oldrot = rot; g2.rotate(rot); } String temp = vcode.substring(i, i + 1); g2.setColor(getRandColor(1, 100)); g2.drawString(temp, 0, 0); } // ͼ����Ч g2.dispose(); return image; } public void printImage(HttpServletRequest request, HttpServletResponse response) { // ��ContentType��Ϊ"image/jpeg"���������ʶ��ͼ���ʽ�� response.setContentType("image/jpeg"); // ����ҳ�治���� response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 2000); // ��������֤�� String verifyCode = this.getRandString(); // �����֤���ͼ����� BufferedImage bi = this.getImage(request); try { // ���Servlet����� ServletOutputStream outStream = response.getOutputStream(); // ������������ͼ����ݱ���ΪJPEG������ı����� JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream); // ��ͼ����ݽ��б��� encoder.encode(bi); // ǿ�н���������������뵽ҳ�� outStream.flush(); // �ر������ outStream.close(); } catch (IOException ex) { ex.printStackTrace(); } } public void doGet(HttpServletRequest request, HttpServletResponse response) { printImage(request, response); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值