Programming Languages
These snippets should be useful to read RAR archives with store compression (which means none compression is used). Feel free to edit/add source-codes if you have faster/better/new language implementation.
Links:
- http://www.unrarlib.org/
- http://www.rarlab.com/rar_add.htm
- http://github.com/jphastings/unrar/ (in Ruby)
- http://libxad.cvs.sourceforge.net/viewvc/libxad/support/formats/RAR202.txt?revision=1.1&view=markup
Python
#(c)Kamil Dzióbek turbos11(at)gmail.com
# BSD License
from struct import *
def getlastsplit(firsrarfile,x):
if firsrarfile[-3:]=='001':
return firsrarfile[:-3]+('%03d' %(x+1))
if firsrarfile[-11:-6]=='.part':
return firsrarfile[0:-6]+('%02d' % (x+1))+firsrarfile[-4:]
if firsrarfile[-10:-5]=='.part':
return firsrarfile[0:-5]+('%1d' % (x+1))+firsrarfile[-4:]
return firsrarfile[0:-2]+('%02d' %(x-1) )
def addfilehash(name,hash,seek):
f=open(name, 'rb')
f.seek(seek)
for i in range(8192):
hash+=unpack('<q', f.read(8))[0]
hash =hash & 0xffffffffffffffff
return hash
def OpensubtitlesHashRar(firsrarfile):
"""Hash file in rar split archive. -> (size,hash)"""
if not(firsrarfile.lower().endswith('.rar') | firsrarfile.endswith('.001')):
raise Exception('Bad file suffix. Only .rar and .001 support.')
if firsrarfile[-11:-6]=='.part':
firsrarfile=firsrarfile[0:-6]+'01'+firsrarfile[-4:]
f=open(firsrarfile, 'rb')
a=f.read(4)
if a!='Rar!':
raise Exception('ERROR: This is not rar file.')
seek=0
for i in range(4):
f.seek(seek)
a=f.read(100)
type,flag,size=unpack( '<BHH', a[2:2+5])
if 0x74==type:
if 0x30!=unpack( '<B', a[25:25+1])[0]:
raise Exception('Bad compression method! Work only for "store".')
s_partiizebodystart=seek+size
s_partiizebody,s_unpacksize=unpack( '<II', a[7:7+2*4])
if (flag & 0x0100):
s_unpacksize=(unpack( '<I', a[36:36+4])[0] <<32 )+s_unpacksize
print 'Hash untested for files biger that 2gb. May work or may generate bad hash.'
lastrarfile=getlastsplit(firsrarfile,(s_unpacksize-1)/s_partiizebody)
hash=addfilehash(firsrarfile,s_unpacksize,s_partiizebodystart)
hash=addfilehash(lastrarfile,hash,(s_unpacksize%s_partiizebody)+s_partiizebodystart-65536)
return (s_unpacksize,"%016x" % hash )
seek+=size
raise Exception('ERROR: Not Body part in rar file.')
#example
firsrarsplitfile='I:\\test.rar'
size,hash=OpensubtitlesHashRar(firsrarsplitfile)
print 'use this valuse on opensubtiles.com\n\tsize is: %d\n\thash is: %s' % (size,hash)
