wiki:RarSourceCodes

Version 1 (modified by os, 15 years ago) (diff)

--

Programming Languages

  1. Python

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:

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)