In C++,
getline() discards the delimiter (newline). Your code is not computing the checksum for the file, just on the lines excluding the newlines.
A quick hack would be to assume that every line has a newline (this is not necessarily true!), and add
Code:
adler = update_adler32(adler, "\n", 1);
after the line checksum update.
A better option would be to read the file into memory as is, say using code similar to
this example at cplusplus.com, and then checksum the entire file.
Here is an example program written in C99 you can use to compare against.
Code:
#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#define ADLER32_BASE 65521
uint32_t adler32(uint32_t const sum, const int descriptor, off_t *const length)
{
unsigned char buffer[32768]; /* Uses a lot of stack! */
ssize_t n;
int saved_errno;
off_t total = 0;
unsigned int sum1 = sum & 0xFFFFU;
unsigned int sum2 = (sum >> 16U) & 0xFFFFU;
saved_errno = errno;
while (1) {
n = read(descriptor, buffer, sizeof buffer);
if (n > (ssize_t)0) {
const unsigned char *head = buffer;
const unsigned char *const tail = buffer + n;
total += (off_t)n;
while (head < tail) {
sum1 = (sum1 + *(head++)) % ADLER32_BASE;
sum2 = (sum2 + sum1) % ADLER32_BASE;
}
continue;
} else
if (n == (ssize_t)-1 && errno == EINTR)
continue;
if (n == (ssize_t)-1)
saved_errno = errno;
else
if (n != (ssize_t)0)
saved_errno = EIO;
if (length)
*length = total;
errno = saved_errno;
return (uint32_t)sum1 + ((uint32_t)sum2 << 16U);
}
}
int main(int argc, char *argv[])
{
uint32_t sum;
off_t length;
int arg, fd, result;
if (argc < 2) {
fprintf(stderr, "\nUsage: %s FILE(s)...\n\n", argv[0]);
return 0;
}
for (arg = 1; arg < argc; arg++) {
do {
fd = open(argv[arg], O_RDONLY | O_NOCTTY);
} while (fd == -1 && errno == EINTR);
if (fd == -1) {
fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
return 1;
}
errno = 0;
sum = adler32(1, fd, &length);
if (errno) {
fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
return 1;
}
printf("%s: 0x%08lx = %lu (%lu bytes)\n",
argv[arg], (unsigned long)sum, (unsigned long)sum, (unsigned long)length);
fflush(stdout);
do {
result = close(fd);
} while (result == -1 && errno == EINTR);
if (result == -1) {
fprintf(stderr, "%s: Error closing file: %s.\n", argv[arg], strerror(errno));
return 1;
}
}
return 0;
}
The
online Adler32 generator you linked to does not seem to work for me. It modifies its input (converting LF newlines to CRLF pairs, and so on), and seems to fail on all file inputs I try with it.
On the other hand,
this one provides the exact same results as my example program above. (To verify you hashed the same data, you can use
sha256sum to check the SHA256 hash of your test file, and compare it to the online one.)
Hope this helps,