0

ファイルとそのファイルの Adler32 チェックサムを Web サービスに送信する目的の c でアプリを開発しています。

ファイルを Web サーバーに送信すると、チェックサムが失敗したとの回答が返されます。

これは、objective-c の合計をチェックするために使用するコードです。

//Get Asset NSData
ALAssetRepresentation *rep = [[p objectForKey:@"assetPath"] defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

//I also need a path to the file so I have to save the NSData to a local file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"png"];
[data writeToFile:localFilePath atomically:YES];
NSString *path = localFilePath;

//Now call the Adler
NSLog(@"checksum_fast:%@", [NSString stringWithFormat:@"%u", adler32_fast([data bytes], [data length])]);
NSLog(@"checksum:%@", [NSString stringWithFormat:@"%u", adler32([data bytes], [data length])]);

//Adler Lib
#define MOD_ADLER 65521
#define BUFFER_SIZE 1000

uint32_t adler32_update(uint32_t ck, const unsigned char data) {
  uint32_t a = ck & 0x0ffff, b = (ck >> 16) & 0x0ffff;
  a = (a + data) % MOD_ADLER;
  b = (b + a) % MOD_ADLER;
  return (b << 16) | a;
}

uint32_t adler32(const unsigned char *data, int data_len) {
  uint64_t ck = 1;
  for(int i=0; i<data_len; i++) {
    ck = adler32_update(ck,data[i]);
  }
  return ck;
}

uint32_t adler32_fast(const unsigned char *data, int data_len) {
  uint32_t a = 1, b = 0;
  for(int i=0; i<data_len; i++) {
    a = (a + data[i]) % MOD_ADLER;
    b = (b + a) % MOD_ADLER;
  }
  return (b << 16) | a;
}

これは C# Web サービスのコードです。

//It use ICSharpCode.SharpZipLib.dll    
byte[] buff = null;
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo(path).Length;
buff = br.ReadBytes((int)numBytes);

Adler32 adler = new Adler32();
adler.Reset();
adler.Update(buff, 0, buff.Length);
fs.Close();
fs.Dispose();
br.Close();
buff = null;
return Convert.ToString(adler.Value, 16);

チェックサムの結果が異なる理由を知っている人はいますか?

テスト ファイル: http://we.tl/gjqSj43238

Adler32 C#: 701ea682 (1881056898)

Adler32 オブジェクト C: 70100C51 (1880099921)

ありがとう!

4

1 に答える 1

2

最も重要なのは、アドラーのスペルが間違っていることです。あなたの定数はMOD_ADLER、ではなく、でなければなりませんMOD_ALDER

すべてのコードを提供していないため、その定数を何に設定したかわかりません。

毎回モジュロ演算を行うため、コードは名前が主張するように「高速」ではありません。モジュロ演算を延期しないのであれば、そこに 2 つのネストされたループを配置しても意味がありません。

1 & 0xFFFFそれは常に であるため、ばかげているよう1です。

エラーは、に初期化bすること1です。に初期化する必要があります0

ああ、別のエラーが表示されます。データ配列unsigned charではなく、を使用する必要があります。char

adler32()実装を zlibにコピーすることをお勧めします。

于 2013-08-28T02:05:47.053 に答える