From 40726e18796aeaac3bbc94e12df363a1607b0866 Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Sun, 25 Sep 2011 18:31:23 +0200 Subject: [PATCH] initial oshash commit --- .bzrignore | 1 + Makefile | 29 ++++++++++++ README | 10 +++++ src/oshash.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 .bzrignore create mode 100644 Makefile create mode 100644 README create mode 100644 src/oshash.c diff --git a/.bzrignore b/.bzrignore new file mode 100644 index 0000000..4f286e7 --- /dev/null +++ b/.bzrignore @@ -0,0 +1 @@ +oshash diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7af8517 --- /dev/null +++ b/Makefile @@ -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 diff --git a/README b/README new file mode 100644 index 0000000..7801ae8 --- /dev/null +++ b/README @@ -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 + diff --git a/src/oshash.c b/src/oshash.c new file mode 100644 index 0000000..1d135d7 --- /dev/null +++ b/src/oshash.c @@ -0,0 +1,125 @@ +/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */ +/* + * oshash.c -- generate oshash for provided files + * Copyright (C) 2011-2011 + * + * 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 . + */ + +#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 +#include +#include +#include +#include +#include +#include +#include + +#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