java CRC16算法,分解一个大Key实例。和各种hash算法代码

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package org.rui.hi;  
  2.   
  3. /** 
  4.  * 测试: 解决场景:把1亿的用户 存储在一个队列里,过大。用sharding 摸拟redis 集群 sharding Redis 
  5.  * 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 
  6.  * 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 
  7.  * key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。 
  8.  *  
  9.  * @author ruiliang 
  10.  * 
  11.  */  
  12. public class HashDist {  
  13.     public final static int maxInt = 1000;// 00000;//1亿  
  14.     public final static int USER_KEY_SLOT_COUNT = 20// 定议分配存储用户的Slot位  
  15.                                                         // ,如果存储有压力,可调大槽位  
  16.   
  17.     public static void main(String[] args) {  
  18.   
  19.         // int 不用crc16  
  20.         for (int i = 1; i < maxInt; i++) {  
  21.             // 根据玩家id 分布指定到Slot位  
  22.             int ranint = i % USER_KEY_SLOT_COUNT;  
  23.             String key = "key:" + ranint;  
  24.             System.out.println("key:" + key);  
  25.             // redisList.lpush(randomKey, String.valueOf(playerId));  
  26.         }  
  27.   
  28.         /** 
  29.          * crc16 redis 集群也是用这种方式分配key 
  30.          */  
  31.   
  32.         String a = "a,b,c,d,e,f,g,g,g";  
  33.         for (String j : a.split(",")) {  
  34.             int solt = CRCJava.crc16(j.getBytes()) % USER_KEY_SLOT_COUNT;  
  35.             String key = "key:" + solt;  
  36.             System.out.println("crc%solt=key:" + key);  
  37.         }  
  38.   
  39.         // redisList.lpush(randomKey, String.valueOf(playerId));  
  40.   
  41.     }  
  42.   
  43. }  
  44. /** 
  45.  * output: ... 
  46.  *  
  47.  * key:key:0 key:key:1 key:key:2 key:key:3 key:key:4 key:key:5 key:key:6 
  48.  * key:key:7 key:key:8 key:key:9 key:key:10 key:key:11 key:key:12 key:key:13 
  49.  * key:key:14 key:key:15 key:key:16 key:key:17 key:key:18 key:key:19 key:key:0 
  50.  * key:key:1 key:key:2 key:key:3 key:key:4 key:key:5 key:key:6 key:key:7 
  51.  * key:key:8 key:key:9 key:key:10 key:key:11 key:key:12 key:key:13 key:key:14 
  52.  * key:key:15 key:key:16 key:key:17 key:key:18 key:key:19 key:key:0 key:key:1 
  53.  * key:key:2 key:key:3 key:key:4 key:key:5 key:key:6 key:key:7 key:key:8 
  54.  * key:key:9 key:key:10 key:key:11 key:key:12 key:key:13 key:key:14 key:key:15 
  55.  * key:key:16 key:key:17 key:key:18 key:key:19 key:key:0 key:key:1 key:key:2 
  56.  * key:key:3 key:key:4 key:key:5 key:key:6 key:key:7 key:key:8 key:key:9 
  57.  * key:key:10 key:key:11 key:key:12 key:key:13 key:key:14 key:key:15 key:key:16 
  58.  * key:key:17 key:key:18 key:key:19 key:key:0 key:key:1 key:key:2 key:key:3 
  59.  * key:key:4 key:key:5 key:key:6 key:key:7 key:key:8 key:key:9 key:key:10 
  60.  * key:key:11 key:key:12 key:key:13 key:key:14 key:key:15 key:key:16 key:key:17 
  61.  * key:key:18 key:key:19 key:key:0 key:key:1 key:key:2 key:key:3 key:key:4 
  62.  * key:key:5 key:key:6 key:key:7 key:key:8 key:key:9 key:key:10 key:key:11 
  63.  * key:key:12 key:key:13 key:key:14 key:key:15 key:key:16 key:key:17 key:key:18 
  64.  * key:key:19 crc%solt=key:key:11 crc%solt=key:key:8 crc%solt=key:key:17 
  65.  * crc%solt=key:key:10 crc%solt=key:key:19 crc%solt=key:key:16 
  66.  * crc%solt=key:key:5 crc%solt=key:key:5 crc%solt=key:key:5 
  67.  */  



[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package org.rui.hi;  
  2.   
  3. public class CRCJava {  
  4.   
  5.     public static void main(String[] args) {  
  6.         String a = "a,b,c,d,e,f,g";  
  7.   
  8.         for (String i : a.split(",")) {  
  9.             System.out.println(crc16(i.getBytes()));  
  10.         }  
  11.         System.out.println("----------------------------------");  
  12.         for (String i : a.split(",")) {  
  13.             System.out.println(crc162(i.getBytes()));  
  14.         }  
  15.   
  16.     }  
  17.   
  18.     /****************************************************************************** 
  19.      * Compilation: javac CRC16CCITT.java Execution: java CRC16CCITT s 
  20.      * Dependencies: 
  21.      *  
  22.      * Reads in a sequence of bytes and prints out its 16 bit Cylcic Redundancy 
  23.      * Check (CRC-CCIIT 0xFFFF). 
  24.      * 
  25.      * 1 + x + x^5 + x^12 + x^16 is irreducible polynomial. 
  26.      * 
  27.      * % java CRC16-CCITT 123456789 CRC16-CCITT = 29b1 
  28.      * 
  29.      ******************************************************************************/  
  30.   
  31.     public static int crc16(final byte[] buffer) {  
  32.   
  33.         int crc = 0xFFFF// initial value 65535  
  34.         int polynomial = 0x1021// 0001 0000 0010 0001 (0, 5, 12)  
  35.         // byte[] testBytes = "123456789".getBytes("ASCII");  
  36.         for (byte b : buffer) {  
  37.             for (int i = 0; i < 8; i++) {  
  38.                 boolean bit = ((b >> (7 - i) & 1) == 1);  
  39.                 boolean c15 = ((crc >> 15 & 1) == 1);  
  40.                 crc <<= 1;  
  41.                 if (c15 ^ bit)  
  42.                     crc ^= polynomial;  
  43.             }  
  44.         }  
  45.   
  46.         return crc &= 0xffff;  
  47.   
  48.     }  
  49.   
  50.     /** 
  51.      *  
  52.      * @param buffer 
  53.      * @return 
  54.      */  
  55.     static int crc162(final byte[] buffer) {  
  56.         int crc = 0xFFFF;  
  57.   
  58.         for (int j = 0; j < buffer.length; j++) {  
  59.             crc = ((crc >>> 8) | (crc << 8)) & 0xffff;  
  60.             crc ^= (buffer[j] & 0xff);// byte to int, trunc sign  
  61.             crc ^= ((crc & 0xff) >> 4);  
  62.             crc ^= (crc << 12) & 0xffff;  
  63.             crc ^= ((crc & 0xFF) << 5) & 0xffff;  
  64.         }  
  65.         crc &= 0xffff;  
  66.         return crc;  
  67.   
  68.     }  
  69. }  

---------------------------------------

各种hash算法

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package org.rui.hi;  
  2.   
  3. /** 
  4.  * 相关hash算法 
  5.  *  
  6.  * @author ruiliang 
  7.  * 
  8.  */  
  9. public class HashTest {  
  10.   
  11.     public static void main(String[] args) {  
  12.   
  13.         // long hash = DEKHash("123456");  
  14.         // System.out.println(hash);  
  15.         System.out.println(hashCode(0));  
  16.         System.out.println(hashCode(1));  
  17.         System.out.println(hashCode(2));  
  18.         System.out.println(hashCode(3));  
  19.         System.out.println(hashCode(123456));  
  20.         System.out.println(hashCode(123457));  
  21.         System.out.println(hashCode(123458));  
  22.   
  23.         System.out.println(PJWHash("0"));  
  24.         System.out.println(PJWHash("1"));  
  25.         System.out.println(PJWHash("2"));  
  26.         System.out.println(PJWHash("3"));  
  27.         System.out.println(PJWHash("123456"));  
  28.         System.out.println(PJWHash("123457"));  
  29.         System.out.println(PJWHash("123458"));  
  30.   
  31.     }  
  32.   
  33.     /** 
  34.      * 从Robert Sedgwicks的 Algorithms in C一书中得到了 
  35.      *  
  36.      * @param str 
  37.      * @return 
  38.      */  
  39.     public static long RSHash(String str) {  
  40.         int b = 378551;  
  41.         int a = 63689;  
  42.         long hash = 0;  
  43.         for (int i = 0; i < str.length(); i++) {  
  44.             hash = hash * a + str.charAt(i);  
  45.             a = a * b;  
  46.         }  
  47.         return hash;  
  48.     }  
  49.   
  50.     /** 
  51.      * Justin Sobel写的一个位操作的哈希函数。 
  52.      *  
  53.      * @param str 
  54.      * @return 
  55.      */  
  56.     public static long JSHash(String str) {  
  57.         long hash = 1315423911;  
  58.         for (int i = 0; i < str.length(); i++) {  
  59.             hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));  
  60.         }  
  61.         return hash;  
  62.     }  
  63.   
  64.     /** 
  65.      * PJW 该散列算法是基于贝尔实验室的彼得J温伯格的的研究。在Compilers一书中(原则,技术和工具),建议采用这个算法的散列函数的哈希方法。 
  66.      *  
  67.      * @param str 
  68.      * @return 
  69.      */  
  70.     public static long PJWHash(String str) {  
  71.         long BitsInUnsignedInt = (long) (4 * 8);  
  72.         long ThreeQuarters = (long) ((BitsInUnsignedInt * 3) / 4);  
  73.         long OneEighth = (long) (BitsInUnsignedInt / 8);  
  74.         long HighBits = (long) (0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);  
  75.         long hash = 0;  
  76.         long test = 0;  
  77.         for (int i = 0; i < str.length(); i++) {  
  78.             hash = (hash << OneEighth) + str.charAt(i);  
  79.             if ((test = hash & HighBits) != 0) {  
  80.                 hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits));  
  81.             }  
  82.         }  
  83.         return hash;  
  84.     }  
  85.   
  86.     /** 
  87.      * ELF 和PJW很相似,在Unix系统中使用的较多。 
  88.      *  
  89.      * @param str 
  90.      * @return 
  91.      */  
  92.     public static long ELFHash(String str) {  
  93.         long hash = 0;  
  94.         long x = 0;  
  95.         for (int i = 0; i < str.length(); i++) {  
  96.             hash = (hash << 4) + str.charAt(i);  
  97.             if ((x = hash & 0xF0000000L) != 0) {  
  98.                 hash ^= (x >> 24);  
  99.             }  
  100.             hash &= ~x;  
  101.         }  
  102.         return hash;  
  103.     }  
  104.   
  105.     /** 
  106.      * BKDR 这个算法来自Brian Kernighan 和 Dennis Ritchie的 The C Programming 
  107.      * Language。这是一个很简单的哈希算法,使用了一系列奇怪的数字,形式如31,3131,31...31,看上去和DJB算法很相似。 
  108.      *  
  109.      * @param str 
  110.      * @return 
  111.      */  
  112.   
  113.     public static long BKDRHash(String str) {  
  114.         long seed = 131// 31 131 1313 13131 131313 etc..  
  115.         long hash = 0;  
  116.         for (int i = 0; i < str.length(); i++) {  
  117.             hash = (hash * seed) + str.charAt(i);  
  118.         }  
  119.         return hash;  
  120.     }  
  121.   
  122.     public static long SDBMHash(String str) {  
  123.         long hash = 0;  
  124.         for (int i = 0; i < str.length(); i++) {  
  125.             hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash;  
  126.         }  
  127.         return hash;  
  128.     }  
  129.   
  130.     /** 
  131.      * DJB 这个算法是Daniel J.Bernstein 教授发明的,是目前公布的最有效的哈希函数。 
  132.      *  
  133.      * @param str 
  134.      * @return 
  135.      */  
  136.     public static long DJBHash(String str) {  
  137.         long hash = 5381;  
  138.         for (int i = 0; i < str.length(); i++) {  
  139.             hash = ((hash << 5) + hash) + str.charAt(i);  
  140.         }  
  141.         return hash;  
  142.     }  
  143.   
  144.     /** 
  145.      * .DEK 由伟大的Knuth在《编程的艺术 第三卷》的第六章排序和搜索中给出。 
  146.      *  
  147.      * @param str 
  148.      * @return 
  149.      */  
  150.     public static long DEKHash(String str) {  
  151.         long hash = str.length();  
  152.         for (int i = 0; i < str.length(); i++) {  
  153.             hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);  
  154.         }  
  155.         return hash;  
  156.     }  
  157.   
  158.     /** 
  159.      * jdk hash 
  160.      *  
  161.      * @param a 
  162.      * @return 
  163.      */  
  164.     public static int hashCode(int a) {  
  165.         final int prime = 48;  
  166.         int result = 1;  
  167.         result = prime * result + a;  
  168.         return result;  
  169.     }  
  170. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值