2011年12月10日星期六

一直以来,我都以为UTF-16和UCS-2是一样的 囧。

UCS-2: 固定双字节表示一个字符,只能表示 UCS 的子集 BMP。
       (UCS-2 扩充后成为 UTF-16,这里我们依然将 UCS-2 指代扩充前的编码方式)
UCS-4: 固定四字节表示一个字符,能表示整个 UCS。
UTF-16: 双字节或者四字节表示一个字符,能表示整个 UCS。
        UCS-2 跟 UTF-16 在 BMP 范围兼容。 UCS-2 是废弃的。
UTF-8: 一种编码方式,一到四个字节(*)表示一个字符,能表示整个 UCS。
UTF-32: 同 UCS-4。

*现在的 Unicode 标准只有 21 位 0 ~ 0x10FFFF

2011年12月9日星期五

使用javamail生成带附件的html邮件

一般来说,带附件并且有图片的html的mime邮件形如以下的格式:

 multipart/mixed
    multipart/related
        multipart/alternative


JavaMail的FAQ没有详细解释如何发送这种多重嵌套multipart的mime邮件。关键是设置content-type为"message/rfc822",见下面示例代码的黑体部分。

public void createMail() {
 ......
 //这里只示例生成Multipart的代码,其他代码请参考JavaMail的相关文档
 Multipart mmp = null;
 mmp = getHtmlPart(plaintext, html);
 mmp = getRelatedPart(mmp, image);
 mmp = getMixedPart(mmp, attachment);
 ......
}

private Multipart getHtmlPart(String plaintext, String html) throws MessagingException {
 MimeMultipart mmp_alt = new MimeMultipart("alternative");
 MimeBodyPart mbp_text = new MimeBodyPart();
 mbp_text.setContent(plaintext, "text/plain;charset=UTF-8");
 mmp_alt.addBodyPart(mbp_text);
 MimeBodyPart mbp_html = new MimeBodyPart();
 mbp_html.setContent(html, "text/html;charset=UTF-8");
 mmp_alt.addBodyPart(mbp_html);

 return mmp_alt;

}

private Multipart getRelatedPart(Multipart aPart, String imagesPath) throws MessagingException, UnsupportedEncodingException {
 MimeMultipart mmp = new MimeMultipart("related");

 MimeBodyPart mbp = new MimeBodyPart();
 mbp.setContent(aPart, "message/rfc822");
 mmp.addBodyPart(mbp);

 String[] imageFiles = imagesPath.split(",");
 if (imageFiles.length != 0) {
  for (String file : imageFiles) {
   MimeBodyPart mbp_file = new MimeBodyPart();
   FileDataSource fds = new FileDataSource(file);
    mbp_file.setDataHandler(new DataHandler(fds));
   mbp_file.setFileName(MimeUtility.encodeText(fds.getName(), "gbk", "B"));
   File f = new File(file);
   mbp_file.setContentID("<" + f.getName() + ">");
   mmp.addBodyPart(mbp_file);
  }
 }
 return mmp;
}

private Multipart getMixedPart(Multipart aPart, String attachPath) throws MessagingException, IOException {
 MimeMultipart mmp = new MimeMultipart("mixed");

 MimeBodyPart mbp = new MimeBodyPart();
 mbp.setContent(aPart, "message/rfc822");
 mmp.addBodyPart(mbp);

 String[] files = attachPath.split(",");
 if (files.length != 0) {
  for (String file : files) {
   MimeBodyPart mbp_file = new MimeBodyPart();
   mbp_file.attachFile(file);
   mbp_file.setHeader("Content-Transfer-Encoding", "base64");
   mmp.addBodyPart(mbp_file);
  }
 }

 return mmp;
}

salt解释

以前翻阅文档是总会遇上salt这个词,但一直没有理解,今天看到这篇文章,才明白是怎么回事。
salt是一串随机(但是对每个用户是固定的,比如用户名、用户id等)的字符串,附加到密码上生成心得字符串,再用这个字符串生成md5,保存到数据库中。
使用salt和单纯的密码md5比较,有2个好处:
1. 增加破解的难度。数据库在被hack的情况下,如果不知道salt的生成规律,是无法简单地通过字典来暴力破解。
2. 增加破解的时间。即使知道salt生成规律,通过字典暴力破解也只能每次破解一个用户的密码,因为每个用户的salt是不一样的,最终生成的md5也不相同。
而如果只简单保存密码的md5,那么不同用户密码相同的时候,可以通过一次sql查询就破解。

顺便吐槽下,salt其实并不难理解,但是在看定义和用途的解释却让人很难理解。说的通俗点,密码是第一把保险锁,而salt则是网站提供的第二把保险锁。