我正在开发一个应用程序,它使用用户位置信息将数据发送到服务器。服务器接受基于校验和计算的数据,这是用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);
}
我试图寻求帮助,以找出如何写出与此相当的客观c。以上功能使用adler32,我对此没有任何线索。请帮忙。
感谢您的时间。
答案 0 :(得分:8)
@achievelimitless和@ user3275097显示的答案不正确。
首先,不应使用带符号的整数。负数的模运算符在不同语言中的定义不同,应尽可能避免使用。简单地使用无符号整数。
其次,循环将快速溢出16位累加器,这将给出错误的答案。模数运算可以延迟,但必须在溢出之前完成。您可以通过假设所有输入字节都是255来计算可以安全执行的循环次数。
第三,由于第二点,你不应该使用16位类型。您应该使用至少32位类型,以避免经常进行模数运算。您仍然需要限制循环次数,但数量会变得更大。对于32位无符号类型,最大循环数为5552.因此基本代码如下所示:
#define MOD 65521
#define MAX 5552
unsigned long adler32(unsigned char *buf, size_t len)
{
unsigned long a = 1, b = 0;
size_t n;
while (len) {
n = len > MAX ? MAX : len;
len -= n;
do {
a += *buf++;
b += a;
} while (--n);
a %= MOD;
b %= MOD;
}
return a | (b << 16);
}
如@Sulthan所述,您应该只使用zlib中提供的adler32()
函数,该函数已经存在于Mac OS X和iOS上。
答案 1 :(得分:-1)
根据wikipedia中提到的adler32校验和的定义,
Objective C实现如下:
static NSNumber * adlerChecksumof(NSString *str)
{
NSMutableData *data= [[NSMutableData alloc]init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
for (int i = 0; i < ([str length] / 2); i++)
{
byte_chars[0] = [str characterAtIndex:i*2];
byte_chars[1] = [str characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[data appendBytes:&whole_byte length:1];
}
int16_t a=1;
int16_t b=0;
Byte * dataBytes= (Byte *)[data bytes];
for (int i=0; i<[data length]; i++)
{
a+= dataBytes[i];
b+=a;
}
a%= 65521;
b%= 65521;
int32_t adlerChecksum= b*65536+a;
return @(adlerChecksum);
}
此处str
将是您问题中提到的字符串..
因此,当您想要计算某些字符串的校验和时,请执行以下操作:
NSNumber * calculatedChkSm= adlerChecksumof(@"1217278743473774374");
如果需要更多信息,请告诉我