initial oshash commit
This commit is contained in:
commit
40726e1879
4 changed files with 165 additions and 0 deletions
1
.bzrignore
Normal file
1
.bzrignore
Normal file
|
@ -0,0 +1 @@
|
|||
oshash
|
29
Makefile
Normal file
29
Makefile
Normal 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
10
README
Normal 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
125
src/oshash.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue