哈希算法(Hash、散列)应用场景小结

  项目中有好几个地方用到了哈希算法,更确切地说,是SHA算法的应用场景。MD5也是常用的哈希算法,但已经被证明不再安全,SHA-1也是如此,不安全的原因主要是彩虹表,或是碰撞计算,这里不详细描述。一般推荐使用SHA-256或者SHA-512,至少在当前是安全的。
  哈希表在代码中也普遍使用,是一种用于关键字查询的数组或顺序列表,这里就不说了。

1. 校验安装文件的完整性
  在软件部署的时候,计算软件包当前的哈希值是否与预设值相等,防止软件包被篡改或被替换。Linux提供了基于sha算法的命令,用于计算文件的哈希值

sha256sum fileName

2. 存储和校验用户口令

  用户口令不能用明文存储,更进一步,如果系统不知道用户口令明文,那就更好了,而哈希算法就可以做到既不知道用户明文,又可以校验用户口令。详见《基于哈希算法的web账户口令存储方法》,http://www.cnblogs.com/todsong/archive/2012/04/22/2465178.html

3. 校验重复提交的消息

  用户可能因为误操作重复提交数据,而这些数据会对系统产生影响,若要拒绝这些消息,最好的方法就是在每次提交时,计算消息的哈希值,当发现疑似重复提交的时候,做消息哈希值的对比。这是一个CPU密集型的操作,如果系统的CPU负载比较低,可以考虑使用。至于如何在代码中使用哈希算法,这里就不描述了,Java、C++都有现成的算法库可用。

4. 作为数据库乐观锁的条件

  数据库中,最常用的乐观锁方法是在表中增加额外的一列,用于记录一行数据的版本值,通常是一个计数或是时间戳。但是,一张已经存在大量数据的表需要增加额外的版本列,似乎不太可行,也不太方便,此时可以通过哈希计算出虚拟的版本列,用于乐观锁定控制。Oracle数据库提供了哈希算法的存储过程,输入某几个列数据的字符连接,输出该条记录的哈希值,通过比较该值判断数据是否被修改。下面是摘自《Oracle 9i&10g 编程艺术》的例子

begin
 for x in ( select deptno, dname, loc
 from dept
 where deptno = 10 )
 loop
 dbms_output.put_line( 'Dname: ' || x.dname );
 dbms_output.put_line( 'Loc: ' || x.loc );
 dbms_output.put_line( 'Hash: ' ||
 dbms_crypto.hash
 ( utl_raw.cast_to_raw(x.deptno||'/'||x.dname||'/'||x.loc),
 dbms_crypto.hash_sh1 ) );
 end loop;
 end;
/

上面存储过程执行的结果是

Dname: ACCOUNTING
Loc: NEW YORK
Hash: C44F7052661CE945D385D5C3F911E70FA99407A6
PL/SQL procedure successfully completed.

5. 作为数据库表分区的分区条件

  如果难以按照某一个列对数据库表做分区,表中的数据又没有太多的业务逻辑,那么通过哈希函数强行分区是个不错的选择。详见《Oracle分区表,哈希分区的新建与增加》,http://www.cnblogs.com/todsong/archive/2012/08/26/2657158.html

原文地址:https://www.cnblogs.com/todsong/p/2686608.html