Bibm@th

Forum de mathématiques - Bibm@th.net

Bienvenue dans les forums du site BibM@th, des forums où on dit Bonjour (Bonsoir), Merci, S'il vous plaît...

Vous n'êtes pas identifié(e).

#1 20-08-2011 14:05:28

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 987

[Pyhon]Codage/décodage par la méthode du "railfence"

Bonjour,

Suite aux récents textes à décoder et codés via cette méthode, j'ai décidé d'écrire un prog de codage/décodage.
Version brute sans interface dans laquelle il faut simplement
* modifier le texte proposé en exemple,
* choisir la valeur de la variable action 0 pour le codage, 1 pour le décodage
* modifier la valeur de la variable rails (ici 5 avec l'exemple donné)

#!/usr/bin/env python
# -*- coding: CP1252 -*-

def titre(a):
    print "                ************************************"
    if a==0:
        print "                *         Codage railfence         *"
    else:
        print "                *        Décodage railfence        *"
    print "                *           Version 1.0            *"
    print "                ************************************\n\n"

   
def decoupe(crypto,rails):
    lg,L=len(crypto),[]
    itv=2*rails-3
    ncc=lg//(itv+1)+(lg%(itv+1)>=1)
    reste=lg-(ncc-1)*(itv+1)-1
    if reste<rails:
        r1,r2=reste,0
    else:
        r1=rails-1
        r2=reste-r1
    fin=ncc
    L.append(crypto[:fin])  
    for j in range(1,rails-1):
        cor=(ncc-1)*2+(r1>=j)+(j>=rails-1-r2)
        db=fin
        fin=db+cor
        L.append(crypto[db:fin])
    L.append(crypto[fin:])
    return L,lg,itv

def contenu_rails(L):
    print "                  * Contenu des",rails,"rails *\n"
    for mot in L:
        print "  -",mot
    print

def affichage_en_scie(L,rails):
    # Si moins de 80 caractères
    print "               * Décodage à lire en \  /\  /\  /  *"
    print "               *                     \/  \/  \/   *\n"
    sp=" "
    j=-1
    for mot in L:
        j+=1
        k=-1
        print sp*j,
        ligne=""
        for lettre in mot:
            k+=1
            if j==0 or j==rails-1:
                espc=sp*(2*rails-3)
            else:
                espc=sp*((2*rails-3-2*j)*(k%2==0)+(2*j-1)*(k%2==1))
            ligne+=lettre+espc
        print ligne.rstrip(" ")
   
def message_decode(L,rails,itv,lg):
    decode=["*"]*lg
    saut=itv+1
    for j in range(rails):
        mot=L[j]
        for i in range(len(mot)):
            if j==0 or j==rails-1:
                decode[j+saut*i]=mot[i]
            else:
                decode[j+saut*(i//2)+(saut-2*j)*(i%2==1)]=mot[i]  
    print "\n"        
    print "                       * Message decodé *\n"
    formate5(decode,lg)

def chiffrage(Texte,rails):
    ini,L="*",[]
    for i in range(rails):
        L+=[[ini]]
    itv=2*rails-3
    saut=itv+1
    cache=""
    lg=len(Texte)
    for i in range(lg):
        if i%saut>rails-1:
            no=saut-(i%saut)
            L[no].append(Texte[i])
        else:
            no=i%saut
            L[no].append(Texte[i])
    for i in range(rails):
        del L[i][0]
        cache+=''.join(L[i])
    formate5(cache,lg)
   
def formate5(Entrant,lg):
    Texte="".join(Entrant)
    coupes=lg//5-(lg%5==0)
    for i in xrange(coupes):
        # Insertion d'un espace tous les 5 caractères dans Texte
        Texte=Texte[0:5+6*i]+" "+Texte[5+6*i:lg]
        lg+=1
    print Texte

# Modifier ci-dessous : Action, Donnee et nombre de rails
action=1
#Recommandation en Python : scinder les textes trop long avec \
Donnee="QANET ARIIN UEFON CNUIS GOTHM TSEIE MACAE OELXE MECER TGEJI IEIRM REUSM\
LRDAE NUART BAIAE IR"
rails=5
# Fin des modifications

# Début du travail
titre(action)
Txt=(Donnee.replace(" ","")).upper()
if action ==0:
    chiffrage(Txt,rails)
else:
    L,lg,itv=decoupe(Txt,rails)
    print "                      * Message codé *\n"
    print Donnee
    print
    contenu_rails(L)
    if lg<80:
        affichage_en_scie(L,rails)
    message_decode(L,rails,itv,lg)

Pour une version avec interface, remplacer les lignes 105 à 126 par :

fin,ok=0,0
while not fin:
    Donnee=raw_input("Entrez le texte à coder/décoder :")
    for a in "',;!?. ":
        Donnee=Donnee.replace(a,'')
    Donnee=Donnee.upper()
    while not ok:
        rep=raw_input(" Voulez-vous coder (0) ou décoder un texte (1) ?")
        try:
            action =int(rep)
            if 0<=action<2:
                ok=1
            else:
                print "Réponse par 0 ou 1, s'il vous plaït"
                ok=0
        except ValueError:
            print "Oops ! Réponse par 0 ou 1. Veuillez recommencer s'il vous plaît !"
            ok=0
    while not ok:
        rep=raw_input("Entrez le nombre de rails (niveaux) >= 2 :  ")
        try:
            rails =int(rep)
            if rails>=2:
                if 2*rails-1<len(Donnee):
                    ok=1
                else:
                    print "Le nombre de rails est trop grand par rapport au texte"
            else:
                print "Le nombre de rails doit être supérieur à 2"                
                ok=0
        except ValueError:
            print "Oops ! Ceci n'est pas un nombre"
           
    titre(action)
    if action ==0:
        chiffrage(Txt,rails)
    else:
        L,lg,itv=decoupe(Txt,rails)
        print "                      * Message codé *\n"
        print Donnee
        print
        contenu_rails(L)
        if lg<80:
            affichage_en_scie(L,rails)
        message_decode(L,rails,itv,lg)
    while not rep=="A":
        rep=(raw_input(" Voulez-vous Arrêter (A) ou continuer (C) ?")).upper()
        if rep=="A":
            fin==1
        elif rep=="C":
            break
        else:
            print "...Entrée incorrecte, veuillez recommencer..."

Et ajouter la procédure :


def titre_collecte_infos():
    print "                ************************************"
    print "                *        Codage/décodage           *"
    print "                *    Méthode du railfence          *"
    print "                ************************************"

 

Réactions/suggestions ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#2 22-08-2011 10:44:33

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 987

Re : [Pyhon]Codage/décodage par la méthode du "railfence"

Bonjour à tous,

J'ai étendu l'écriture en de scie sur 2 séries de ligne au lieu d'une (jusqu'à 150 caractères).
Pour cela remplacer les lignes les lignes 40 à 58 du premier code complet (sans interface) par :

def affichage_en_scie(R,rails):
    # Si moins de 150 caractères
    print "               * Décodage à lire en \  /\  /\  /  *"
    print "               *                     \/  \/  \/   *\n"
    itv=2*rails-3
    ncc,saut=lg//(itv+1)+(lg%(itv+1)>=1),itv+1
    lim,bs=80//saut,1+(80<lg<=150)
    for l in range(bs):
        L=[]
        for i in range(rails):
            bn,d=len(R[i]),1+(0<i<rails-1)
            L.append(R[i][d*lim*l:d*lim*(l==0)+bn*(l==1)])
        j,sp=-1," "
        for mot in L:
            j+=1
            k,bl,ligne=-1,sp*j,""
            for lettre in mot:
                k+=1
                if j==0 or j==rails-1:
                    espc=sp*itv
                else:
                    espc=sp*((itv-2*j)*(k%2==0)+(2*j-1)*(k%2==1))
                ligne+=lettre+espc
            print bl+ligne.strip()
        print "\n"

Et voilà le résultat :

                ************************************
                *        Décodage railfence        *
                *           Version 1.0            *
                ************************************


                      * Message codé *

QANET ARIIN DETAO NERNU EFONC NUISG OTHMT SEIIE GMUPL VPUOP MEAEA TEMAC AEOEL XEMEC ERTGE UTUEE RRARR TREUP IVAJI IEIRM REUSM LRDAE NUQOJ NPIEL UMIOL TELAG SARTB AIAEI RNTSE OBDSE

                  * Contenu des 5 rails *

  - QANETARIINDETAONERN
  - UEFONCNUISGOTHMTSEIIEGMUPLVPUOPMEAEAT
  - EMACAEOELXEMECERTGEUTUEERRARRTREUPIVA
  - JIIEIRMREUSMLRDAENUQOJNPIELUMIOLTELAGS
  - ARTBAIAEIRNTSEOBDSE


               * Décodage à lire en \  /\  /\  /  *
               *                     \/  \/  \/   *
 

11082211084519663.png


                       * Message décodé *

QUEJA IMEAF AIREC ONNAI TRECE NOMBR EUTIL EAUXS AGESI MMORT ELARC HIMED EARTI STEIN GENIE URQUI DETON JUGEM ENTPE UTPRI SERLA VALEU RPOUR MOITO NPROB LEMEE UTDEP AREIL SAVAN TAGES

Si vous n'utilisez pas l'IDLE de Windows ou tout autre interface graphique et si vous double-cliquez directement sur le progrrame enregistré, maintenez la fenêtre ouverte en notant tout en fin de programme :
touche=raw_input()
et vous appuierez sur Entrée pour fermer...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#3 23-08-2011 10:28:28

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 987

Re : [Pyhon]Codage/décodage par la méthode du "railfence"

Bonjour à tous,

Version 1.2 avec ou sans interface...
Changelog :
- Correction d'un bug d'affichage sur la sortie écran des "dents de scie" : plus de débordements possibles en 2e série
- Correction d'affichages divers, dont :
  * formattage de l'affichage de sortie du texte (codé ou décodé) en lignes de 13 groupes de 5
  * adaptation du premier message à l'action demandée : message clair po message codé (au lieu de message codé dans les 2 cas)
- Ajout d'une temporisation en fin de version sans interface en cas de sortie en console "DOS"

#!/usr/bin/env python
# -*- coding: CP1252 -*-

from __future__ import division
from math import ceil


def titre(a):
    print "                ************************************"
    if a==0:
        print "                *         Codage railfence         *"
    else:
        print "                *        Décodage railfence        *"
    print "                *           Version 1.2            *"
    print "                ************************************\n"

   
def decoupe(crypto,rails):
    lg,L=len(crypto),[]
    itv=2*rails-3
    ncc=lg//(itv+1)+(lg%(itv+1)>=1)
    reste=lg-(ncc-1)*(itv+1)-1
    if reste<rails:
        r1,r2=reste,0
    else:
        r1=rails-1
        r2=reste-r1
    fin=ncc
    L.append(crypto[:fin])  
    for j in range(1,rails-1):
        cor=(ncc-1)*2+(r1>=j)+(j>=rails-1-r2)
        db=fin
        fin=db+cor
        L.append(crypto[db:fin])
    L.append(crypto[fin:])
    return L,lg,itv

def contenu_rails(L):
    print "                  * Contenu des",rails,"rails *\n"
    for mot in L:
        print "  -",mot
    print

def affichage_en_scie(R,rails,saut):
    print "                  * Décodage à lire en \/\/\/\/ *"
    print                                  
    itv=saut-1
    ncc=lg//(itv+1)+(lg%(itv+1)>=1)
    lim,bs=80//saut,1+(lg>80)
    for l in range(bs):
        L=[]
        for i in range(rails):
            bn,d=len(R[i]),1+(0<i<rails-1)
            L.append(R[i][d*lim*l:d*lim*(l==0)+bn*(l==1)])
        j,sp=-1," "
        for mot in L:
            j+=1
            k,bl,ligne=-1,sp*j,""
            for lettre in mot:
                k+=1
                if j==0 or j==rails-1:
                    espc=sp*itv
                else:
                    espc=sp*((itv-2*j)*(k%2==0)+(2*j-1)*(k%2==1))
                ligne+=lettre+espc
            print bl+ligne.strip()
        print
       
def message_decode(L,rails,itv,lg):
    decode=["*"]*lg
    saut=itv+1
    for j in range(rails):
        mot=L[j]
        for i in range(len(mot)):
            if j==0 or j==rails-1:
                decode[j+saut*i]=mot[i]
            else:
                decode[j+saut*(i//2)+(saut-2*j)*(i%2==1)]=mot[i]        
    print " "*23+"* Message décodé *\n"
    formate5(decode,lg)

def chiffrage(Texte,rails):
    ini,L="*",[]
    for i in range(rails):
        L+=[[ini]]
    itv=2*rails-3
    saut=itv+1
    cache=""
    lg=len(Texte)
    for i in range(lg):
        if i%saut>rails-1:
            no=saut-(i%saut)
            L[no].append(Texte[i])
        else:
            no=i%saut
            L[no].append(Texte[i])
    for i in range(rails):
        del L[i][0]
        cache+=''.join(L[i])
    print  " "*23+"* Message decodé *\n"
    formate5(cache,lg)
   
def formate5(Entree,lg):
    Texte="".join(Entree)
    coupes=lg//5-(lg%5==0)
    for i in xrange(coupes):
        # Insertion d'un espace tous les 5 caractères dans Texte
        Texte=Texte[0:5+6*i]+" "+Texte[5+6*i:lg]
        lg+=1
    fin=int(ceil(lg/77))
    for j in range(fin):
        cs=77*(j+1)+(j>0)
        if cs>lg:
            cs = lg
        print " "+Texte[77*j+(j>0):cs].strip()

###################################################
# Modifier ci-dessous : Action, Donnee et nombre de rails
act=1
#Recommandation en Python : scinder les textes trop long avec \
Donnee="QANET ARIIN DETAO NERNU EFONC NUISG OTHMT SEIIE GMUPL VPUOP MEAEA TEMAC \
AEOEL XEMEC ERTGE UTUEE RRARR TREUP IVAJI IEIRM REUSM LRDAE NUQOJ NPIEL UMIOL \
TELAG SARTB AIAEI RNTSE OBDSE"
rails=5
# Fin des modifications

###################################################

# Début du travail
titre(act)
Txt,saut=(Donnee.replace(" ","")).upper(),2*rails-2
print " "*23+"* Message "+"claircodé"[5*act:5*act+5-act]+" *\n"
print Donnee,"\n"
if act==0:
    chiffrage(Txt,rails)
else:
    L,lg,itv=decoupe(Txt,rails)
    contenu_rails(L)
    if lg-((80//saut)*saut)<80:
        affichage_en_scie(L,rails,saut)
    message_decode(L,rails,itv,lg)

print "\n"
touche=raw_input("                 Pour quiter, appuyez sur Entrée")

Pour la version avec interface, remplacer les lignes 1117 à 144 ci dessus par :

fin,ok=0,0
while not fin:
    Donnee=raw_input("Entrez le texte à coder/décoder :")
    for a in "',;!?. ":
        Donnee=Donnee.replace(a,'')
    Donnee=Donnee.upper()
    while not ok:
        rep=raw_input(" Voulez-vous coder (0) ou décoder un texte (1) ?")
        try:
            act =int(rep)
            if 0<=act<2:
                ok=1
            else:
                print "Réponse par 0 ou 1, s'il vous plaït"
                ok=0
        except ValueError:
            print "Oops ! Réponse par 0 ou 1. Veuillez recommencer s'il vous plaît !"
            ok=0
    while not ok:
        rep=raw_input("Entrez le nombre de rails (niveaux) >= 2 :  ")
        try:
            rails =int(rep)
            if rails>=2:
                if 2*rails-1<len(Donnee):
                    ok=1
                else:
                    print "Le nombre de rails est trop grand par rapport au texte"
            else:
                print "Le nombre de rails doit être supérieur à 2"                
                ok=0
        except ValueError:
            print "Oops ! Ceci n'est pas un nombre"            
    titre(act)
    Txt,saut=(Donnee.replace(" ","")).upper(),2*rails-2
    print " "*23+"* Message "+"claircodé"[5*act:5*act+5-act]+" *\n"
    print Donnee,"\n"
    if act==0:
        chiffrage(Txt,rails)
    else:
        L,lg,itv=decoupe(Txt,rails)
        contenu_rails(L)
        if lg-((80//saut)*saut)<80:
            affichage_en_scie(L,rails,saut)
        message_decode(L,rails,itv,lg)
    while not rep=="A":
        rep=(raw_input(" Voulez-vous Arrêter (A) ou continuer (C) ?")).upper()
        if rep=="A":
            fin==1
        elif rep=="C":
            break
        else:
            print "...Entrée incorrecte, veuillez recommencer..."

Remarques, suggestions ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

Réponse rapide

Veuillez composer votre message et l'envoyer
Nom (obligatoire)

E-mail (obligatoire)

Message (obligatoire)

Programme anti-spam : Afin de lutter contre le spam, nous vous demandons de bien vouloir répondre à la question suivante. Après inscription sur le site, vous n'aurez plus à répondre à ces questions.

Quel est le résultat de l'opération suivante (donner le résultat en chiffres)?
cinquante huit moins quaranteet un
Système anti-bot

Faites glisser le curseur de gauche à droite pour activer le bouton de confirmation.

Attention : Vous devez activer Javascript dans votre navigateur pour utiliser le système anti-bot.

Pied de page des forums