我想知道adler32校验和与md5校验和相比有多可靠?在维基百科上告诉我,adler32"比md5"更"可靠",所以我想知道它有多少,以及以哪种方式?
更具体地说,我想知道它是否足够可靠作为长期存档大小为20GB +的(tar)文件的一致性检查?
Adler-32校验和算法总和模数为65521.我知道65521是最大的素数,适合16位,但为什么在这个算法中使用素数很重要?
(我确信一旦有人告诉我,答案就会显而易见,但我脑中的数论理论部分却无法正常工作.即使没有校验和算法方面的专业知识,一个聪明的人也会阅读http://en.wikipedia. org/wiki/Fletcher%27s_checksum可能会向我解释.)
当使用adler32()作为哈希函数时,应该会遇到罕见的冲突.
我们可以对碰撞概率进行精确计算,但粗略地说,
因为它是一个32位散列函数,所以
在几千个项目的样本集上不应该有很多碰撞.
情况并非如此.
这是一个例子:让我们采取包含中间日期的字符串,例如
"Some prefix text " + date + " some postfix text."
Run Code Online (Sandbox Code Playgroud)
其中,dates`格式为yyyy-mm-dd,并在2012年循环.
这个例子中有91次碰撞!
更糟糕的是:有7个案例发生了3个日期相撞.
为什么这种常用的哈希函数表现如此糟糕?
或者我错过了什么?
以下是上述示例的详细结果:
0x592a0f1f: 2012-01-30, 2012-02-02, 2012-10-21
0x592b0f1f: 2012-02-11, 2012-10-30, 2012-11-02
0x593d0f20: 2012-01-31, 2012-02-03, 2012-10-22
0x593e0f20: 2012-02-12, 2012-10-31, 2012-11-03
0x59410f20: 2012-03-11, 2012-11-30, 2012-12-02
0x59560f21: 2012-03-30, 2012-04-02, 2012-12-21
0x59690f22: 2012-03-31, 2012-04-03, 2012-12-22
0x59020f1d: 2012-01-10, 2012-10-01
0x59150f1e: 2012-01-11, 2012-10-02
0x59160f1e: 2012-01-20, 2012-10-11
0x59170f1e: 2012-02-01, 2012-10-20
0x59180f1e: 2012-02-10, 2012-11-01
0x59280f1f: 2012-01-12, 2012-10-03
0x59290f1f: 2012-01-21, 2012-10-12
0x592c0f1f: 2012-02-20, 2012-11-11
0x592d0f1f: 2012-03-01, 2012-11-20
0x592e0f1f: 2012-03-10, …
Run Code Online (Sandbox Code Playgroud) 我需要从JavaScript对象创建校验和.
不幸的是,由于JavaScript的对象排序,似乎没有一种简单的方法可以实现这一点.例如,取这些对象:
var obj1 = {type:"cake",quantity:0}
, obj2 = {quantity:0,type:"cake"};
Run Code Online (Sandbox Code Playgroud)
我认为这些对象在数据上是相同的,并且希望它们的校验和是相同的.只要它们中的数据相同,我就真的不关心Object的顺序.
唉,JSON.stringify
两者实际上并不相同; 作为对象的校验和的唯一方法是通过它的String表示,并且JSON.stringify
-ed表示不相等,我的校验和将不相等!
我提出的一个解决方案是基于预定义的模式重新创建Object,如下所示:
var schema = ["type","quantity"];
function sortify(obj,schema){
var n={};
for(i in schema)
n[schema[i]]=obj[schema[i]];
return n
}
Run Code Online (Sandbox Code Playgroud)
运行JSON.stringify(sortify(obj1,schema))==JSON.stringify(sortify(obj2,schema))
将返回true
...但是以创建新对象并在数据周围移动为代价.
我的另一个解决方案是将JSON.stringify
方法替换为从预定义模式中选择键并对其值进行字符串化,然后将它们连接在一起的方法.功能如下:
function smarterStringify(obj,schema){
var s="";
for(i in schema)
s+=JSON.stringify(obj[schema[i]]);
return s
}
Run Code Online (Sandbox Code Playgroud)
忽略这个方法没有返回正确的JSON(它足够接近作为我正在尝试做的一个例子)这一事实,它比速度上的第一个提升了很多(至少在我的Chrome OS浏览器中,你可以在这里自己检查:http://jsperf.com/sort-then-json-stringify-vs-smarter-stringify),当然它使两个Object String表示相等!
但是,我只是想知道我是否遗漏了某些东西并且有一个内置的方法,这样的事情一直没有a)驱动JavaScript GC进入病态案例或b)做太多的字符串连接.我宁愿不做那些.
我正在使用zlib的adler32函数来计算一块内存x(长度为4096)的弱校验和.一切都很好,但是现在我想执行滚动校验和,如果来自不同文件的块不匹配,但是,我不知道如何编写一个函数来执行zlib中adler32返回的值.因此,如果校验和不匹配,如何使用原始校验和,x + 1字节和x + 4096 + 1来计算滚动校验和?基本上试图建立rsync实现.
提前致谢.
我正在使用adler32校验和算法从数据库ID生成一个数字.因此,当我在数据库中插入一行时,我会获取该行的标识并使用它来创建校验和.我遇到的问题是我刚刚在数据库中插入了207个后才生成重复校验和.这比我预期的要快得多.这是我的代码:
String dbIdStr = Long.toString(dbId);
byte[] bytes = dbIdStr.getBytes();
Checksum checksum = new Adler32();
checksum.update(bytes, 0, bytes.length);
result = checksum.getValue();
Run Code Online (Sandbox Code Playgroud)
我在做什么/怎么做有什么问题吗?我应该使用不同的方法来创建唯一的字符串吗?我这样做是因为我不想在url中使用db id ...对db结构的更改将破坏世界上所有的链接.
谢谢!
有谁知道通过组合散列函数是否有降低碰撞概率的真正好处?我特别需要知道32位散列,即组合Adler32和CRC32. 基本上,adler32(crc32(data))会产生比crc32(数据)更小的碰撞概率吗?这里 的最后一条评论给出了一些有利于组合的测试结果,但没有提到任何来源.出于我的目的,碰撞并不重要(即任务不涉及安全性),但如果可能的话,我宁愿尽可能地减少概率.PS:我刚开始在哈希的精彩世界里,做了很多关于它的阅读.对不起,如果我问一个愚蠢的问题,我还没有获得正确的"哈希方言",可能我的谷歌搜索也很差.谢谢.
我正在 go 中实现adler32 checksum的滚动版本。
这个答案有助于仔细检查我的数学。然而我很难在 golang 中正确实现它。
我写了以下代码:
func roll(adler, n, leave, enter uint32) uint32 {
a := adler & 0xffff
b := adler >> 16
a = (a + enter - leave) % MOD
b = (b - n*leave - 1 + a) % MOD
return b<<16 | a
}
Run Code Online (Sandbox Code Playgroud)
它在各种输入上进行了测试,并且运行良好,直到我决定在随机数据上运行它。这是一个不起作用的示例(我找到了其中几个)。
令我困惑的是,Python 中的相同代码在这些输入上完美运行:
def roll(adler, n, leave, enter):
a = adler & 0xffff
b = adler >> 16
a = (a + …
Run Code Online (Sandbox Code Playgroud) 在计算运行的校验和时需要澄清。
假设我有这样的数据。
data = 'helloworld'
Run Code Online (Sandbox Code Playgroud)
假设块大小为5,我需要计算运行校验和。
>>> zlib.adler32('hello')
103547413
>>> zlib.adler32('ellow')
105316900
Run Code Online (Sandbox Code Playgroud)
根据Python文档(Python版本2.7.2)
zlib.adler32(data[, value])
Run Code Online (Sandbox Code Playgroud)
“计算数据的Adler-32校验和。(Adler-32校验和几乎与CRC32一样可靠,但是可以更快地计算出来。)如果存在value,则将其用作校验和的起始值;否则,使用固定的默认值。这允许在多个输入的串联上计算运行中的校验和。”
但是当我提供这样的东西时,
>>> zlib.adler32('ellow', zlib.adler32('hello'))
383190072
Run Code Online (Sandbox Code Playgroud)
输出完全不同。
我尝试创建一个自定义函数以生成rsync算法中定义的滚动校验和。
def weakchecksum(data):
a = 1
b = 0
for char in data:
a += (ord(char)) % MOD_VALUE
b += a % MOD_VALUE
return (b << 16) | a
def rolling(checksum, removed, added, block_size):
a = checksum
b = (a >> 16) & 0xffff
a &= 0xffff
a = (a - ord(removed) + ord(added)) % MOD_VALUE
b = …
Run Code Online (Sandbox Code Playgroud) 我正在开发一个应用程序,它使用用户位置信息向服务器发送数据.服务器接受基于校验和计算的数据,这是用java编写的.
这是用Java编写的代码:
private static final String CHECKSUM_CONS = "1217278743473774374";
private static String createChecksum(double lat, double lon) {
int latLon = (int) ((lat + lon) * 1E6);
String checkSumStr = CHECKSUM_CONS + latLon;
byte buffer[] = checkSumStr.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
CheckedInputStream cis = new CheckedInputStream(bais, new Adler32());
byte readBuffer[] = new byte[50];
long value = 0;
try {
while (cis.read(readBuffer) >= 0) {
value = cis.getChecksum().getValue();
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
return String.valueOf(value);
} …
Run Code Online (Sandbox Code Playgroud)