« Petits exemples de code Python » : différence entre les versions

De knowledge
Aller à la navigation Aller à la recherche
mAucun résumé des modifications
Ligne 1 : Ligne 1 :
== Script pour générer automatiquement des mots de passes ==
Dans la section [[Bash random|bash traitant des la génération du hasard]] j'avais mis un exemple de générateur de lot de passe.
Ici on fait un programme python pour faire ça mais en gérant les contraintes des systèmes modernes.
Les règles :
      • contenir au moins un caractère de la classe majuscule (A-Z)
     • contenir au moins un caractère de la classe minuscule (a-z)
     • contenir au moins un caractère de la classe chiffre (0-9)
     • contenir au moins un caractère de la classe caractère spécial parmi ! , . / ? & _ * + = - > < @ ^ # £ µ §
     • NE PAS contenir plus de trois caractères de types identiques consécutifs.
Une longueur de mot de passe réglable avec une taille par défaut de 15 et un minimum de 8.<syntaxhighlight lang="python3">
import argparse
import random
import string
# Define character classes
LOWERCASE = string.ascii_lowercase
UPPERCASE = string.ascii_uppercase
DIGITS = string.digits
SPECIALS = "!,.?/&_*+=-<@^#£µ§"
ALL_CHARS = LOWERCASE + UPPERCASE + DIGITS + SPECIALS
def get_char_type(char):
    """Identifies the type of a character."""
    if char in LOWERCASE:
        return 'lower'
    if char in UPPERCASE:
        return 'upper'
    if char in DIGITS:
        return 'digit'
    if char in SPECIALS:
        return 'special'
    return None
def has_required_chars(password):
    """Checks if the password contains at least one of each required character type."""
    return (any(c in LOWERCASE for c in password) and
            any(c in UPPERCASE for c in password) and
            any(c in DIGITS for c in password) and
            any(c in SPECIALS for c in password))
def no_more_than_three_consecutive(password):
    """
    Checks that the password does not contain more than three consecutive
    characters of the same type.
    """
    if len(password) < 4:
        return True
   
    for i in range(len(password) - 3):
        char1_type = get_char_type(password[i])
        char2_type = get_char_type(password[i+1])
        char3_type = get_char_type(password[i+2])
        char4_type = get_char_type(password[i+3])
        if char1_type == char2_type == char3_type == char4_type:
            return False
    return True
def generate_password(length):
    """
    Generates a password that meets all specified criteria.
    """
    while True:
        # Ensure the password has at least one of each required character type
        password_chars = [
            random.choice(LOWERCASE),
            random.choice(UPPERCASE),
            random.choice(DIGITS),
            random.choice(SPECIALS)
        ]
       
        # Fill the rest of the password length with random characters
        remaining_length = length - len(password_chars)
        if remaining_length > 0:
            password_chars.extend(random.choices(ALL_CHARS, k=remaining_length))
       
        # Shuffle the characters to avoid predictable patterns
        random.shuffle(password_chars)
        password = "".join(password_chars)
       
        # Check if the generated password meets all criteria
        if has_required_chars(password) and no_more_than_three_consecutive(password):
            return password
def main():
    """Main function to parse arguments and generate password."""
    parser = argparse.ArgumentParser(
        description="Generate a secure password with specific criteria."
    )
    parser.add_argument(
        "-n",
        "--length",
        type=int,
        default=12,
        help="The length of the password to generate (default: 12)."
    )
    args = parser.parse_args()
    if args.length < 8:
        print("Error: Password length must be at least 8 to meet all criteria.")
        return
    password = generate_password(args.length)
    print(password)
if __name__ == "__main__":
    main()
</syntaxhighlight>Son usagle est indentique sous windows (power shell) et Linux (bash) :<syntaxhighlight lang="text">
$ python ./password_generator.py
6C#+q4Tq8d=t
</syntaxhighlight>
== Script pour éviter le delog automatique et afficher l'heure ==
== Script pour éviter le delog automatique et afficher l'heure ==
Souvent les connexions à la console ssh ont un time-out d'inactivité très (trop) court.
Souvent les connexions à la console ssh ont un time-out d'inactivité très (trop) court.

Version du 24 août 2026 à 08:13

Script pour générer automatiquement des mots de passes

Dans la section bash traitant des la génération du hasard j'avais mis un exemple de générateur de lot de passe.

Ici on fait un programme python pour faire ça mais en gérant les contraintes des systèmes modernes.

Les règles :

      • contenir au moins un caractère de la classe majuscule (A-Z)

     • contenir au moins un caractère de la classe minuscule (a-z)

     • contenir au moins un caractère de la classe chiffre (0-9)

     • contenir au moins un caractère de la classe caractère spécial parmi ! , . / ? & _ * + = - > < @ ^ # £ µ §

     • NE PAS contenir plus de trois caractères de types identiques consécutifs.

Une longueur de mot de passe réglable avec une taille par défaut de 15 et un minimum de 8.

import argparse
import random
import string

# Define character classes
LOWERCASE = string.ascii_lowercase
UPPERCASE = string.ascii_uppercase
DIGITS = string.digits
SPECIALS = "!,.?/&_*+=-<@^#£µ§"
ALL_CHARS = LOWERCASE + UPPERCASE + DIGITS + SPECIALS

def get_char_type(char):
    """Identifies the type of a character."""
    if char in LOWERCASE:
        return 'lower'
    if char in UPPERCASE:
        return 'upper'
    if char in DIGITS:
        return 'digit'
    if char in SPECIALS:
        return 'special'
    return None

def has_required_chars(password):
    """Checks if the password contains at least one of each required character type."""
    return (any(c in LOWERCASE for c in password) and
            any(c in UPPERCASE for c in password) and
            any(c in DIGITS for c in password) and
            any(c in SPECIALS for c in password))

def no_more_than_three_consecutive(password):
    """
    Checks that the password does not contain more than three consecutive
    characters of the same type.
    """
    if len(password) < 4:
        return True
    
    for i in range(len(password) - 3):
        char1_type = get_char_type(password[i])
        char2_type = get_char_type(password[i+1])
        char3_type = get_char_type(password[i+2])
        char4_type = get_char_type(password[i+3])
        if char1_type == char2_type == char3_type == char4_type:
            return False
    return True

def generate_password(length):
    """
    Generates a password that meets all specified criteria.
    """
    while True:
        # Ensure the password has at least one of each required character type
        password_chars = [
            random.choice(LOWERCASE),
            random.choice(UPPERCASE),
            random.choice(DIGITS),
            random.choice(SPECIALS)
        ]
        
        # Fill the rest of the password length with random characters
        remaining_length = length - len(password_chars)
        if remaining_length > 0:
            password_chars.extend(random.choices(ALL_CHARS, k=remaining_length))
        
        # Shuffle the characters to avoid predictable patterns
        random.shuffle(password_chars)
        password = "".join(password_chars)
        
        # Check if the generated password meets all criteria
        if has_required_chars(password) and no_more_than_three_consecutive(password):
            return password

def main():
    """Main function to parse arguments and generate password."""
    parser = argparse.ArgumentParser(
        description="Generate a secure password with specific criteria."
    )
    parser.add_argument(
        "-n",
        "--length",
        type=int,
        default=12,
        help="The length of the password to generate (default: 12)."
    )
    args = parser.parse_args()

    if args.length < 8:
        print("Error: Password length must be at least 8 to meet all criteria.")
        return

    password = generate_password(args.length)
    print(password)

if __name__ == "__main__":
    main()

Son usagle est indentique sous windows (power shell) et Linux (bash) :

$ python ./password_generator.py 
6C#+q4Tq8d=t

Script pour éviter le delog automatique et afficher l'heure

Souvent les connexions à la console ssh ont un time-out d'inactivité très (trop) court.

Voici un petit programme python qui affiche l'heure au centre de l'écran et attends l'appuy sur une touche.

#!/bin/python3
import time 
import sys
import select
import termios
import tty
import shutil
import hashlib

hashcode="dcc07eeab919998abfedd85c8946b83754501d8d"


# Obtenir la taille du terminal
size = shutil.get_terminal_size()
cols = size.columns
rows = size.lines

# FORMAT 
date_format=" \u25C0\u25C0   %Y-%m-%d    %H:%M:%S   \u25B6\u25B6 ";
# Calcul de la chaine
ssize=len(time.strftime(date_format))

# Calculer la position centrale
center_x = (cols // 2)-(ssize//2)
center_y = rows // 2

#  sleep_time  to ajuste animation
sleep_time=0.03
phase=0

# Sauvegarder les paramètres du terminal
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
tty.setcbreak(fd)  # Mode caractère par caractère
time_start=time.time()
time_stop=time_start+0.5
time_slice=time_stop-time_start
count=0
increment=1 
    

print ("\033[?25l\033[s",end="")
try:
    while True:
        try:
            if select.select([sys.stdin], [], [], 0)[0]:
                key = sys.stdin.read(1)
                if key in ('q', 'Q', '\033'):             
                    print(f"\033[{center_y-1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y+1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H\033[0mEnter code:______\033[6D",end="", flush=True)
                    code=input()
                    hash_input_code = hashlib.sha1(code.encode()).hexdigest()
                    if hash_input_code == hashcode:
                       break
                if key in ('t', 'T'):               
                    print(f"\033[{center_y-1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y+1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H\033[0m time slice:{time_slice:.5f} \033[6D",end="", flush=True)
                    code=input()
                if key in ('s', 'S'):
                    print(f"\033[{center_y-1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y+1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H\033[0m sleep:{sleep_time:.5f} \033[6D",end="", flush=True)
                    code=input()
                if key in ('p', 'P'):
                    print(f"\033[{center_y-1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y+1};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H"+" "*ssize, end="")
                    print(f"\033[{center_y};{center_x}H\033[0m phase:{phase:.5f} \033[6D",end="", flush=True)
                    code=input()
                    
                    
            print(f"\033[{center_y-1};{center_x}H\033[0m Screen lock 'q' or <esc> to exit", end="")
            print(f"\033[{center_y};{center_x}H", end="")
            now = time.time()
            ts=time.localtime(now)
            f=time.strftime("\033[103m\033[31m"+date_format+"\033[0m",ts)
            print (f,end="",flush=True)
            
            print(f"\033[{center_y+1};{center_x}H",end="")
            ## Ajust frequency
            if time_slice>0.95 and time_slice<1.05:         # > 95% Green
                print ("\033[92m",end="")                
            else:
                if time_slice>0.75 and time_slice<1.25:     # > 75% Yellow
                    print ("\033[93m",end="")
                else:
                    print ("\033[31m",end="")               # <75% red
       
            ## print time arrow
  
            print (" "*count,end="",flush=True)
            if increment > 0:
                print (f"-> ",end="",flush=True)
            else:
                print (f"<- ",end="",flush=True)
            time.sleep(sleep_time)
            count+=increment
            if count>=ssize-2:
                time_start=time.time()
                increment=-1
            if count<=0:
                time_stop=time.time()
                time_slice=abs(time_stop-time_start)
                if time_slice < 1:
                    t=time.time()
                    phase=t-int(t)
                    sleep_time+=0.001
                else:   
                    sleep_time-=0.001
                    if sleep_time<0:
                        sleep_time=0                
                increment=+1
            te=time.time()
        except KeyboardInterrupt:
            print("\007", end="", flush=True)
        

finally:
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)  # Restaurer terminal
    print(f"\033[{center_y-1};{center_x}H"+" "*ssize, end="")
    print(f"\033[{center_y};{center_x}H"+" "*ssize, end="")
    print(f"\033[{center_y+1};{center_x}H"+" "*ssize, end="")

    print("\033[u\033[?25h", end="")  # Restaurer position curseur

Le script s'autoexplique. On utilise le module time el des codes ansi.

L'heure et la date s'affiche au milieu de l'écran avec le carret qui disparait. Si on tape une touche on remplace le texte jaune de la date par des espaces,le carret réapparait et le curseur revient là ou il était.

Si il y avait du texte sous la date comme c'est le cas dans cet exemple il sera perdu et remplacé par des espaces.