Outils pour utilisateurs

Outils du site


octets_fichier

Traitement des octets d'un fichier (pour cryptage/décryptage par ex.)

Objectif

On veut traiter rapidement tous les octets d'un fichier et les enregistrer dans un autre fichier. Par exemple pour faire une inversion de bits, ou une rotation, etc…

Code proposé

Il faut d'abord une fonction de lecture-écriture de blocs de caractères. J'ai adapté pour cela ma fonction de copie de fichier:

def traitementfichier(nfcs, nfcd, lgbuf=16384):
    """Traitement des octets d'un fichier et écriture du résultat dans un autre fichier"""
    fs = None
    fd = None
    try:
        fs = open(nfcs, 'rb')
        fd = open(nfcd, 'wb')
        while True:
            buf = fs.read(lgbuf)
            if buf=="":
                break
            # ....
            # ici, traitement de buff qui est une chaine de lgbuf caractères
            # (ce traitement ne doit pas changer le nombre de caractères!!!)
            buf = traitementbuf(buf)  
            # ....
            fd.write(buf)
        fs.close()
        fd.close()
    except:
        if fs != None:
            fs.close()
        if fd != None:
            fd.close()
        raise IOError # relance l'erreur pour la transmettre a l'appelant

Cette fonction lit des blocs 'buf' qui sont des chaines de caractères, appelle le traitement traitementbuf(buf). celui-ci transforme la chaine buf en liste d'octets, modifie les octets, et reconstitue à la fin la chaine (qui doit faire le même nombre de caractères). Cette chaine modifiée est écrite dans le fichier destination. Ceci jusqu'à la fin du fichier source (quand buf==“”).

On peut modifier à l'appel la taille du buffer (lgbuf=longueur de la chaine buf lue et écrite). Attention: le dernier buf lu n'a pas forcément la longueur lgbuf: ça dépend de la longueur totale du fichier!

Pour le traitement des octets, j'ai pris ici l'exemple d'une rotation d'un bit à droite, avec réinjection du bit de droite à gauche de l'octet:

rotd = lambda b: (b>>1) | ((b&1)<<7)

Par exemple,

b = 92  => 01011100
rotd(b) => 00101110
 
b = 93 =>  01011101
rotd(b) => 10101110

Ce qui donne:

def traitementbuf(buf):
    bloc = [ord(c) for c in buf] # conversion de la chaine en liste d'octets
    # ....
    # ici, traitement des octets (= entiers de 0 à 255) de la liste bloc
    # par exemple: rotation à droite d'un bit de tous les octets
    bloc = [rotd(b) for b in bloc]
    # ....
    return ''.join([chr(b) for b in bloc])  # retour de la chaine modifiée

Et voilà comment on utilise ça (exemple ici sous Windows):

nfcs = r"C:\Users\Public\Documents\Wallpaper\FR-wp6.jpg"
nfcd = r"C:\Users\Public\Documents\Wallpaper\FR-wp6_modif.jpg"
try:
    traitementfichier(nfcs, nfcd)
except IOError:
    print u"erreur de lecture/écriture"

J'ai essayé sur le fichier FR-wp6.jpg (du Windows 7) qui fait 775832 octets et le traitement est rapide (dans la seconde).


Amusez-vous bien!

octets_fichier.txt · Dernière modification: 2010/01/14 21:01 de tyrtamos

Outils de la page