crc16算法

package org.rui.hi;
 
/**
 * 测试: 解决场景:把1亿的用户 存储在一个队列里,过大。用sharding 摸拟redis 集群 sharding Redis
 * 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384
 * 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键
 * key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
 * 
 * @author ruiliang
 *
 */
public class HashDist {
	public final static int maxInt = 1000;// 00000;//1亿
	public final static int USER_KEY_SLOT_COUNT = 20; // 定议分配存储用户的Slot位
														// ,如果存储有压力,可调大槽位
 
	public static void main(String[] args) {
 
		// int 不用crc16
		for (int i = 1; i < maxInt; i++) {
			// 根据玩家id 分布指定到Slot位
			int ranint = i % USER_KEY_SLOT_COUNT;
			String key = "key:" + ranint;
			System.out.println("key:" + key);
			// redisList.lpush(randomKey, String.valueOf(playerId));
		}
 
		/**
		 * crc16 redis 集群也是用这种方式分配key
		 */
 
		String a = "a,b,c,d,e,f,g,g,g";
		for (String j : a.split(",")) {
			int solt = CRCJava.crc16(j.getBytes()) % USER_KEY_SLOT_COUNT;
			String key = "key:" + solt;
			System.out.println("crc%solt=key:" + key);
		}
 
		// redisList.lpush(randomKey, String.valueOf(playerId));
 
	}
 
}
/**
 * output: ...
 * 
 * key:key:0 key:key:1 key:key:2 key:key:3 key:key:4 key:key:5 key:key:6
 * key:key:7 key:key:8 key:key:9 key:key:10 key:key:11 key:key:12 key:key:13
 * key:key:14 key:key:15 key:key:16 key:key:17 key:key:18 key:key:19 key:key:0
 * key:key:1 key:key:2 key:key:3 key:key:4 key:key:5 key:key:6 key:key:7
 * key:key:8 key:key:9 key:key:10 key:key:11 key:key:12 key:key:13 key:key:14
 * key:key:15 key:key:16 key:key:17 key:key:18 key:key:19 key:key:0 key:key:1
 * key:key:2 key:key:3 key:key:4 key:key:5 key:key:6 key:key:7 key:key:8
 * key:key:9 key:key:10 key:key:11 key:key:12 key:key:13 key:key:14 key:key:15
 * key:key:16 key:key:17 key:key:18 key:key:19 key:key:0 key:key:1 key:key:2
 * key:key:3 key:key:4 key:key:5 key:key:6 key:key:7 key:key:8 key:key:9
 * key:key:10 key:key:11 key:key:12 key:key:13 key:key:14 key:key:15 key:key:16
 * key:key:17 key:key:18 key:key:19 key:key:0 key:key:1 key:key:2 key:key:3
 * key:key:4 key:key:5 key:key:6 key:key:7 key:key:8 key:key:9 key:key:10
 * key:key:11 key:key:12 key:key:13 key:key:14 key:key:15 key:key:16 key:key:17
 * key:key:18 key:key:19 key:key:0 key:key:1 key:key:2 key:key:3 key:key:4
 * key:key:5 key:key:6 key:key:7 key:key:8 key:key:9 key:key:10 key:key:11
 * key:key:12 key:key:13 key:key:14 key:key:15 key:key:16 key:key:17 key:key:18
 * key:key:19 crc%solt=key:key:11 crc%solt=key:key:8 crc%solt=key:key:17
 * crc%solt=key:key:10 crc%solt=key:key:19 crc%solt=key:key:16
 * crc%solt=key:key:5 crc%solt=key:key:5 crc%solt=key:key:5
 */
package org.rui.hi;
 
public class CRCJava {
 
	public static void main(String[] args) {
		String a = "a,b,c,d,e,f,g";
 
		for (String i : a.split(",")) {
			System.out.println(crc16(i.getBytes()));
		}
		System.out.println("----------------------------------");
		for (String i : a.split(",")) {
			System.out.println(crc162(i.getBytes()));
		}
 
	}
 
	/******************************************************************************
	 * Compilation: javac CRC16CCITT.java Execution: java CRC16CCITT s
	 * Dependencies:
	 * 
	 * Reads in a sequence of bytes and prints out its 16 bit Cylcic Redundancy
	 * Check (CRC-CCIIT 0xFFFF).
	 *
	 * 1 + x + x^5 + x^12 + x^16 is irreducible polynomial.
	 *
	 * % java CRC16-CCITT 123456789 CRC16-CCITT = 29b1
	 *
	 ******************************************************************************/
 
	public static int crc16(final byte[] buffer) {
 
		int crc = 0xFFFF; // initial value 65535
		int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
		// byte[] testBytes = "123456789".getBytes("ASCII");
		for (byte b : buffer) {
			for (int i = 0; i < 8; i++) {
				boolean bit = ((b >> (7 - i) & 1) == 1);
				boolean c15 = ((crc >> 15 & 1) == 1);
				crc <<= 1;
				if (c15 ^ bit)
					crc ^= polynomial;
			}
		}
 
		return crc &= 0xffff;
 
	}
 
	/**
	 * 
	 * @param buffer
	 * @return
	 */
	static int crc162(final byte[] buffer) {
		int crc = 0xFFFF;
 
		for (int j = 0; j < buffer.length; j++) {
			crc = ((crc >>> 8) | (crc << 8)) & 0xffff;
			crc ^= (buffer[j] & 0xff);// byte to int, trunc sign
			crc ^= ((crc & 0xff) >> 4);
			crc ^= (crc << 12) & 0xffff;
			crc ^= ((crc & 0xFF) << 5) & 0xffff;
		}
		crc &= 0xffff;
		return crc;
 
	}
}
package org.rui.hi;
 
/**
 * 相关hash算法
 * 
 * @author ruiliang
 *
 */
public class HashTest {
 
	public static void main(String[] args) {
 
		// long hash = DEKHash("123456");
		// System.out.println(hash);
		System.out.println(hashCode(0));
		System.out.println(hashCode(1));
		System.out.println(hashCode(2));
		System.out.println(hashCode(3));
		System.out.println(hashCode(123456));
		System.out.println(hashCode(123457));
		System.out.println(hashCode(123458));
 
		System.out.println(PJWHash("0"));
		System.out.println(PJWHash("1"));
		System.out.println(PJWHash("2"));
		System.out.println(PJWHash("3"));
		System.out.println(PJWHash("123456"));
		System.out.println(PJWHash("123457"));
		System.out.println(PJWHash("123458"));
 
	}
 
	/**
	 * 从Robert Sedgwicks的 Algorithms in C一书中得到了
	 * 
	 * @param str
	 * @return
	 */
	public static long RSHash(String str) {
		int b = 378551;
		int a = 63689;
		long hash = 0;
		for (int i = 0; i < str.length(); i++) {
			hash = hash * a + str.charAt(i);
			a = a * b;
		}
		return hash;
	}
 
	/**
	 * Justin Sobel写的一个位操作的哈希函数。
	 * 
	 * @param str
	 * @return
	 */
	public static long JSHash(String str) {
		long hash = 1315423911;
		for (int i = 0; i < str.length(); i++) {
			hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));
		}
		return hash;
	}
 
	/**
	 * PJW 该散列算法是基于贝尔实验室的彼得J温伯格的的研究。在Compilers一书中(原则,技术和工具),建议采用这个算法的散列函数的哈希方法。
	 * 
	 * @param str
	 * @return
	 */
	public static long PJWHash(String str) {
		long BitsInUnsignedInt = (long) (4 * 8);
		long ThreeQuarters = (long) ((BitsInUnsignedInt * 3) / 4);
		long OneEighth = (long) (BitsInUnsignedInt / 8);
		long HighBits = (long) (0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
		long hash = 0;
		long test = 0;
		for (int i = 0; i < str.length(); i++) {
			hash = (hash << OneEighth) + str.charAt(i);
			if ((test = hash & HighBits) != 0) {
				hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits));
			}
		}
		return hash;
	}
 
	/**
	 * ELF 和PJW很相似,在Unix系统中使用的较多。
	 * 
	 * @param str
	 * @return
	 */
	public static long ELFHash(String str) {
		long hash = 0;
		long x = 0;
		for (int i = 0; i < str.length(); i++) {
			hash = (hash << 4) + str.charAt(i);
			if ((x = hash & 0xF0000000L) != 0) {
				hash ^= (x >> 24);
			}
			hash &= ~x;
		}
		return hash;
	}
 
	/**
	 * BKDR 这个算法来自Brian Kernighan 和 Dennis Ritchie的 The C Programming
	 * Language。这是一个很简单的哈希算法,使用了一系列奇怪的数字,形式如31,3131,31...31,看上去和DJB算法很相似。
	 * 
	 * @param str
	 * @return
	 */
 
	public static long BKDRHash(String str) {
		long seed = 131; // 31 131 1313 13131 131313 etc..
		long hash = 0;
		for (int i = 0; i < str.length(); i++) {
			hash = (hash * seed) + str.charAt(i);
		}
		return hash;
	}
 
	public static long SDBMHash(String str) {
		long hash = 0;
		for (int i = 0; i < str.length(); i++) {
			hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash;
		}
		return hash;
	}
 
	/**
	 * DJB 这个算法是Daniel J.Bernstein 教授发明的,是目前公布的最有效的哈希函数。
	 * 
	 * @param str
	 * @return
	 */
	public static long DJBHash(String str) {
		long hash = 5381;
		for (int i = 0; i < str.length(); i++) {
			hash = ((hash << 5) + hash) + str.charAt(i);
		}
		return hash;
	}
 
	/**
	 * .DEK 由伟大的Knuth在《编程的艺术 第三卷》的第六章排序和搜索中给出。
	 * 
	 * @param str
	 * @return
	 */
	public static long DEKHash(String str) {
		long hash = str.length();
		for (int i = 0; i < str.length(); i++) {
			hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);
		}
		return hash;
	}
 
	/**
	 * jdk hash
	 * 
	 * @param a
	 * @return
	 */
	public static int hashCode(int a) {
		final int prime = 48;
		int result = 1;
		result = prime * result + a;
		return result;
	}
}

各种hash算法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CRC(Cyclic Redundancy Check)循环冗余校验是一种简单且高效的错误检测算法,广泛应用于数据传输中的错误检测和校正。 CRC8和CRC16是两种常用的CRC校验算法。其中,CRC8算法用于校验8位字节或数据流的校验和,CRC16算法则用于校验16位字节或数据流的校验和。 CRC16算法CRC8算法更复杂,但CRC16的校验结果更可靠。CRC16算法在计算校验和时,使用一个16位的生成多项式,并且每次处理一个16位数据流。而CRC8算法则使用一个8位的生成多项式,每次处理一个8位数据流。 具体来说,CRC8算法首先需要一个初始值,然后依次读入每个数据字节,进行位运算和异或操作,最终计算出一个8位的校验和。CRC16算法与其类似,只不过初始化值更大,多项式也更长,计算结果也是一个16位的校验和。 虽然CRC算法的实现较为复杂,但它被广泛运用于通信和数据传输领域,因为它可以快速检测并校正数据传输过程中出现的错误。 ### 回答2: CRC算法是一种很常见的校验算法,其中最常见的两种是crc8和crc16算法CRC8算法是将传输的数据进行异或运算,并采取模2除法,将结果存储于一个8位寄存器中,最后输出8位的校验码。这种算法主要用于串行通信协议、存储设备和传感器网络。 CRC16算法是将输入数据除以一个特定的多项式,余数即为校验码。这种算法具有很高的误检率,可以在大多数场合用于通信的数据完整性检验。常见的应用包括:以太网、通讯协议、Modbus、X.25、SD卡等。与CRC8相比,CRC16可以检测更多的错误位。 在实际应用中,CRC算法通常需要选取合适的生成多项式,来保证算法的稳定性和准确性。同时,为了避免非正常条件下的错误数据干扰,可以在校验码中加入一定的冗余信息。 ### 回答3: CRC(Cyclic Redundancy Check)是一种校验算法,主要用于检测数据传输的出错情况。在计算机通信、存储等领域广泛应用。CRC算法可以检测出数据传输过程中的单比特差错和位移差错,但是它并不能检测出所有的差错。CRC算法是一种哈希函数的变种,通常采用多项式计算方法。 CRC算法的计算可以分为两个部分:生成表格和计算crc值。生成表格是为了在计算crc过程中快速地查找异或表格的值,而不必每次都进行一次多项式除法。生成表格的方法是将0~255的所有值带入多项式中进行计算,得到一个256位的表格。计算crc值时,将数据流和发送方预设的一个初始值一起丢进异或表格,对每一位进行异或,最后得到的结果就是crc值。 CRC算法有各种各样的规范,如CRC8、CRC16等,不同的规范所采用的多项式也不尽相同。其中,CRC8是一种8位循环冗余校验码,常用于通信协议中,如Modbus、I2C。CRC16是一种16位循环冗余校验码,常用于串口协议和Modbus RTU。 基于不同的多项式,CRC8和CRC16的校验强度也不同。通常来说,CRC16的校验强度要比CRC8高。但是由于CRC16需要计算的多项式位数较多,所以在计算速度上要比CRC8慢。因此,在实际应用中,需要根据具体的场景选择不同的CRC算法。 总之,CRC8和CRC16算法是数据通信中经常使用的一种校验算法。它能够快速检测出数据传输过程中的错误,保证数据的完整性和可靠性。在实际应用中,需要根据不同的场景和要求选择不同的CRC算法,以实现更好的校验效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值