分类 默认分类 下的文章

webp 图片格式

webp 读作[weppy], 是 google 于2010年推出的一种有损压缩格式, 比 png 和 jpeg 大幅减少文件大小, 但是转换过程需要更长时间.
现在只有 chrome 和 opera 浏览器支持这种文件格式, 并且保存到 windows, mac, linux 现在都无法打开, 编辑.

facebook 在2013年开始在网站上使用这种格式, 国内的淘宝上面也在使用这种格式. 这种格式会使客户端和服务器端大大减少网络流量, 因为网站的图片占据了网站的大部分流量.

查看浏览器的支持情况, 查看这里: http://caniuse.com/webp
官方: https://developers.google.com/speed/webp/?csw=1

参考: http://en.wikipedia.org/wiki/WebP

Mac 下的 java 安装路径

Mac 上的 Java 安装过好多次 JDK 1.7 但是等到真正在 eclipse 里面切换系统 library 的时候, 却找不到它了, 只在下面的路径看到系统默认的 JDK 1.6

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/

在 stackoverflow 上查到如下命令:

/usr/libexec/java_home -v 1.7

发现原来另外安装的 JDK 1.7 在下面这个位置:

superman:~ root$ /usr/libexec/java_home -v 1.7
/Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home

参考: Where is Java 7 Installed on Mac OS X?

用户注册, 登录, 密码的存储

以下的思路中有的是说的注册过程, 有的是登录的过程, 大概类似, 注册存储到 DB, 验证只是对比结果.
对于单向加密算法, 用的比较多的是 md5 或者 SHA1, 这里以 md5 为例.

最简单, 最原始:
客户端 密码: 123456 -------------> 服务器端 存储到数据库 123456

服务器端加密存储
客户端 密码: 123456 -------------> 服务器端 加密后存储到数据库 md5(123456)

客户端加密 再传输
客户端 先加密: md5(123456) -------------> 服务器端 直接存储到数据库 md5(123456)

加盐 加密 再传输
客户端 获得 salt <-----------------------服务器端 给 salt
客户端 先加盐, 再加密: md5(123456 + salt) -------------> 服务器端 直接存储到数据库 md5(123456 + salt)

加盐 加密 再 https 传输 (安全通道)
客户端 <----------- 建立 ssl 安全通道 ---------------> 服务器端
客户端 获得 salt <-----------https---------服务器端 给 salt
客户端 先加盐, 再加密: md5(123456 + slat) -----https-----> 服务器端 直接存储到数据库 md5(123456 + salt)

加盐 加密 再 https 传输 (安全通道) 一用户一盐
客户端 <----------- 建立 ssl 安全通道 ---------------> 服务器端
客户端 获得本用户的 salt <---------https-------服务器端 从盐表获取当前用户的salt (盐表单独 server, 单独数据, 单独表)
客户端 先加盐, 再加密: md5(123456 + slat) ----https-------> 服务器端 直接存储到数据库 md5(123456 + salt)

加盐 加密 再 https 传输 (安全通道) 一用户一盐 双因子认证
客户端 <----------- 建立 ssl 安全通道 ---------------> 服务器端
客户端 获得本用户的 salt <---------https-------服务器端 从盐表获取当前用户的salt (盐表单独 server, 单独数据, 单独表)
客户端 获得第二个因子, 如 短信验证码, hard token, soft token, 邮箱获取验证码 <==另外方式===> 服务器端
客户端 先加盐, 再加密: md5(123456 + slat) 第二个因子 ----https-------> 服务器端 双因子 认证 加密后密码 + 第二因子

java.lang.Object 的 hashCode 方法 注意事项

hashCode: digests the data stored in an instance of the class into a single hash value (a 32-bit signed integer);
Technically, in Java, hashCode() by default is a native method, it is implemented directly in the native code in the JVM.

主要用在 hashTable, hashSet, HashMap等需要hash值的数据结构(hash-based collections), 有了这种离散分布的hash值, 对比操作更快;

基本的要求规范是(The hashCode contract):

1) 一个对象如果没有变化, 那么它返回的hashCode值必须前后一致;
2) 两个对象如果是 equals = true, 那么他们的hashCode 值必须一样;

没有要求说, 不同的JVM实现, 必须返回一致的hashCode值. 即使同一段程序, 在不同的执行(Run)当中, 也可以返回不同的hashCode值;
不同的对象, 返回同样的hash值, 是可以接受的(当然最好(理想)的情况下, 是返回不一样的hashCode值);
返回同样 hashCode值的对象, 不要求必须 equals;

为什么: 两个对象如果是 equals = true, 那么他们的hashCode 值必须一样?

举一个反例: 假如2个对象实例是equals的, 但是hashCode值不一样, 那么把它们两个同时放到一个hashSet, 那么它们就占用2个位置了, 但是因为它们是equals的, 所以我们认为它们应该在这个hashSet中只占一个位置, 是同一个值.

一个重写的例子 (奇数->更好的离散型):
An object’s hashCode method must take the same fields into account as its equals method.

public class Employee {
    int        employeeId;
    String     name;
    Department dept;
 
    // other methods would be in here 
 
    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 17 + employeeId;
        hash = hash * 31 + name.hashCode();
        hash = hash * 13 + (dept == null ? 0 : dept.hashCode());
        return hash;
    }
}

HashCode collisions

Whenever two different objects have the same hash code, we call this a collision. A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap lookup has to look again to find the right object. A lot of collisions will degrade the performance of a system, but they won’t lead to incorrect results.
But if you mistake the hash code for a unique handle to an object, e.g use it as a key in a Map, then you will sometimes get the wrong object. Because even though collisions are rare, they are inevitable. For example, the Strings "Aa" and "BB" produce the same hashCode: 2112. Therefore, Never misuse hashCode as a key

there’s one important detail in the hashCode contract that can be quite surprising: hashCode does not guarantee the same result in different executions.

Moreover, you should be aware that the implementation of a hashCode function may change from one version to another. Therefore your code should not depend on any particular hash code values. For example, your should not use the hash code to persist state. Next time you run the application, the hash codes of the “same” objects may be different.

java.lang.String 的hashCode 实现

public int hashCode() {
    if (hashCode == 0) {
        int hash = 0, end = offset + count;
        for (int i = offset; i < end; i++) {
            hash = (hash << 5) - hash + value[i];
        }
        hashCode = hash;
    }
    return hashCode;
}

参考:

  1. wiki
  2. The 3 things you should know about hashCode()

网站访问 -> 代理 ip 检测 -> 端口扫描 -> nmap

看网站的后台浏览记录, 最近发现经常有这么一个网址: mianfeidaili.ttju.cn, 入口是这个网址, 浏览页面竟然也是这个网址. 可以猜测这是一个网页代理, 因为是访问的这个页面, 所以入口和浏览页面的网址都是这个页面.

顺着这个网址找过去, 发现是个: "提供代理IP提取" 的网站. 百度了一下, 发现类似的网站都是提供代理 ip 地址的. 通过某些扫描软件, 发现某一网段, 或者某一运营商(电信,联通,移动)的 ip 段内的免费代理. 然后卖个用户, 用户可以用这些代理刷投票等.

ip 端检测方面比较出名的是 nmap, 它可以 1) 检测该 ip 是否有对应的主机, 该主机是否 up, 2) 那些端口是对外开放的, 是什么协议, 3) 对应的操作系统是什么.

路由器 repo 上竟然有 nmap 软件, 安装之后试了试, 基本的扫描主机还可以. 如果扫描端口什么的, CPU 就飙升了.

eric@home:/tmp/home/eric# nmap -PS21 223.166.19.225/29

Starting Nmap 5.35DC1 ( http://nmap.org ) at 2014-05-25 17:44 UTC
Nmap scan report for 223.166.19.225
Host is up (0.00070s latency).

Nmap scan report for 223.166.19.226
Host is up (0.0027s latency).
Not shown: 997 closed ports
PORT     STATE    SERVICE
23/tcp   filtered telnet
80/tcp   open     http
1900/tcp open     upnp

Nmap done: 8 IP addresses (2 hosts up) scanned in 2138.07 seconds

如上所示, 我扫描了一下我主机所在的 IP 段的一个非常小的部分. 共有8个 IP 地址, 有2个主机 up, 其中上面那个是我的路由器. 下面是另外一台在线的主机. 竟然开着80端口. 不过80端口返回403. 另外还开着1900, 是 upnp 协议.