initial oshash commit

This commit is contained in:
j 2011-09-25 18:31:23 +02:00
commit 40726e1879
4 changed files with 165 additions and 0 deletions

1
.bzrignore Normal file
View file

@ -0,0 +1 @@
oshash

29
Makefile Normal file
View file

@ -0,0 +1,29 @@
PROG = oshash
SRC = src/oshash.c
PREFIX ?= /usr/local
BINDIR ?= ${DESTDIR}${PREFIX}/bin
MAN1DIR ?= ${DESTDIR}${PREFIX}/man/man1
CC ?= gcc
CFLAGS += -Wall -ffast-math -fsigned-char
CFLAGS += -I. -Isrc
INSTALL = install
all: ${PROG}
${PROG}: ${SRC}
${CC} ${CFLAGS} -o ${PROG} $< ${LDFLAGS}
clean:
-@rm -f ${PROG} *~ core *.core src/*.o
install: ${PROG}
${INSTALL} -c -m 555 -o root -g bin ${PROG} ${BINDIR}
uninstall:
@rm -f ${BINDIR}/${PROG}
.PHONY: all install uninstall

10
README Normal file
View file

@ -0,0 +1,10 @@
oshash - Print oshash for files.
Hash code is based on Media Player Classic.
In natural language it calculates:
size + 64bit chksum of the first and last 64k
(even if they overlap because the file is smaller than 128k).
This hash can be used to check for subtitles on opensubtitles.org
http://trac.opensubtitles.org/projects/opensubtitles/wiki/MovieIdentification

125
src/oshash.c Normal file
View file

@ -0,0 +1,125 @@
/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
/*
* oshash.c -- generate oshash for provided files
* Copyright (C) 2011-2011 <j@v2v.cc>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with This program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#if !defined(_LARGEFILE_SOURCE)
#define _LARGEFILE_SOURCE
#endif
#if !defined(_LARGEFILE64_SOURCE)
#define _LARGEFILE64_SOURCE
#endif
#if !defined(_FILE_OFFSET_BITS)
#define _FILE_OFFSET_BITS 64
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <math.h>
#include <errno.h>
#include <sys/stat.h>
#ifndef WIN32
#if !defined(off64_t)
#define off64_t off_t
#endif
#endif
#ifdef WIN32
#define fseeko fseeko64
#define ftello ftello64
#endif
#ifdef _BIG_ENDIAN
#define htonll(x) \
((((x) & 0xff00000000000000LL) >> 56) | \
(((x) & 0x00ff000000000000LL) >> 40) | \
(((x) & 0x0000ff0000000000LL) >> 24) | \
(((x) & 0x000000ff00000000LL) >> 8) | \
(((x) & 0x00000000ff000000LL) << 8) | \
(((x) & 0x0000000000ff0000LL) << 24) | \
(((x) & 0x000000000000ff00LL) << 40) | \
(((x) & 0x00000000000000ffLL) << 56))
#else
#define htonll(x) x
#endif
/*
* os hash
* based on public domain example from
* http://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes
*
* plus modification for files < 64k, buffer is filled with file data and padded with 0
*/
unsigned long long gen_oshash(char const *filename) {
FILE *file;
int i;
unsigned long long t1=0;
unsigned long long buffer1[8192*2];
int used = 8192*2;
file = fopen(filename, "rb");
if (file) {
//add filesize
fseeko(file, 0, SEEK_END);
t1 = ftello(file);
fseeko(file, 0, SEEK_SET);
if(t1 < 65536) {
used = t1/8;
fread(buffer1, used, 8, file);
} else {
fread(buffer1, 8192, 8, file);
fseeko(file, -65536, SEEK_END);
fread(&buffer1[8192], 8192, 8, file);
}
for (i=0; i < used; i++)
t1+=htonll(buffer1[i]);
fclose(file);
}
return t1;
}
void print_oshash(FILE *output, char const *filename) {
char hash[32];
#ifdef WIN32
sprintf(hash, "%016I64x", gen_oshash(filename));
#else
sprintf(hash, "%016qx", gen_oshash(filename));
#endif
if (strcmp(hash,"0000000000000000") > 0)
fprintf(output, "%s %s\n", hash, filename);
}
int main(int argc, char **argv) {
int i;
FILE* output = stdout;
if(argc == 1) {
fprintf(stderr, "usage: %s [filename]\n", argv[0]);
exit(1);
}
for(i=1;i<argc;i++)
print_oshash(output, argv[i]);
return 0;
}