Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 22/01/2013, à 16:16

Yannou90

Bash : permuter mots et creation de phrase à partir d'un dictionnaire

CETTE PREMIERE PARTIE EST OBSOLETE , CE REFERER AU LIEN CI DESSOUS POUR LES NOUVEAUTEES ET AVANCEES

Edit_1 : traitement par fichier , beaucoup plus rapide
Edit_2 : améliorations
Edit_3 : gestions des options et intéractions avec l'utilisateur
Edit_4 : choix du mode de sortie , fichier et stdout , ou fichier seulement
Edit_5 : grosse maj , limitation du poid de sortie , affichage de statistique , reecriture du code ...
Edit_6 : corrections de bugs et optimisations , modifications des options , possibilitée de limiter la creation a n phrases , ultra compression
Edit_7 : version 4.0.2 du 03.02.2013 : corrections de bugs , choix du séparateur entre les mots

Bonjour à tous !

J'ai développé un petit script tout bidon pour , à partir d'une liste de mots (dico) , créer des phrases suivant cette définition :

-on choisi le nombre de mots de la phrase
-on choisi la taille des mots au minimum (nombre de charactères par mot)
-on choisi la taille des mots au maximum (nombre de charactères par mot)

On peut réccupérer toute les compositions possible sur stdout : 2 mots , 3 mots , ... , nbr de mots défini .
Le fichier final ne contient que des phrases contenant exactement le nombre de mots défini , sans doublon , sans répétition du même mot dans la phrase .

Résultat : toute les permutations possible de mots pour composer la phrase sont créées et stocker dans un nouveau dictionnaire.

Ce script à surtout pour but de démontrer l'inutilitée du force brute sur des mots de passes complexes , mais met en avant la plus grande faiblesse de ces mots de passes : l'utilisateur .

Ce script est donné à titre éducatif et ludique ,

Dernière modification par Yannou90 (Le 03/02/2013, à 13:33)

Hors ligne

#2 Le 22/01/2013, à 20:09

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Bon je me répond roll

La solution était pourtante évidente , pfffffff , dès fois je n'ai pas les yeux en face des trou !!

Il faut appliquer un traitement sur le fichier et non ligne par ligne :

#!/bin/bash

# Script : permute.sh par Yannou90
# Utilisation : /chemin/vers/permute.sh <NBR de mot> <NBR de charactere minimum par mot> <NBR de charactere maximum par mot> /chemin/vers/dico.txt
# Fichier de sortie : dico.txt dans le répertoire du dictionnare utilisé

FILE="$4"
DIR="${FILE%/*}"
SEQ="$1"
LONGMIN="$2"
LONGMAX="$3"
NUM="1"
DICO="dico.txt"
NEW="working.txt"
TMP="tmp.txt"

cd "$DIR"

rm "$DICO"
pw-inspector -m "$LONGMIN" -M "$LONGMAX" -i "$FILE" -o "$DICO"
cp "$DICO" "$NEW"

while [[ ! "$NUM" = "$SEQ" ]]
do
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			grep -v "$WORD" "$NEW" | sed -e "s/^/$WORD /g" >> "$TMP"
		fi
	done < "$DICO"
	sort -u "$TMP" > "$NEW"
	rm "$TMP"
	(( NUM++ ))
done

mv -f "$NEW" "$DICO"
		
exit $?

Pour comparer avec le precedent script :
Un fichier de 71 octets composé de 15 mots , on trouve 336336 phrase pour un poid final de 7980 octets -> 7.9Mio , la sortie de time :

real	0m1.873s
user	0m2.976s
sys	0m0.144s

Hors ligne

#3 Le 22/01/2013, à 20:20

nicolas66

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Intérêt du script ? smile


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#4 Le 22/01/2013, à 21:06

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

En soit aucun puisque si lancé sur un gros fichier on aurrait tôt fait d'exploser son disque dur

Plus personnelement je m'interresse au brute-force sur wpa qui est totalement illusoir sur nos box française , ce qui m'as ammener à penser a quoi peut bien servir des dico de plusieurs giga puisqu'ils ne representent qu'une petite partie des possibilité.

Pour tester je me suis auto hacker ( capture du handshake sur freebox v6) , et ensuite brute-force du mot de passe
Le hic est que j'ai mis une clee pas si betont mais suffisement compliquer pour qu'un hacker mette quelque siecle à trouver .

Du coup je peux affirmer que le brute-force est un pure délire !

Par contre , un tout petit dico bien manipulé peu etre utile : ma cle wpa est du type :

tunaurrajamaismasupercledecryptage

Je me suis demandé si en manipulant les mots d'un dictionnaire francais je pouvais trouver ma cle : oui bien sur , mais il me faudrait quelque siecle et quelque petra octet

J'ai cherché à creer un petit programme qui pourrais manipuler les mots d'un dictionnaire en les assemblants sous certains critere , c'est juste un exercice de style , il est complement inutile tongue

Hors ligne

#5 Le 23/01/2013, à 15:40

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Le même en plus rapide encore mad
Toujours aucun intêret , mais je pense avoir trouvé le moyen de ne pas "stocker" les phrases , ... !

La suite au prochain numéros lol

#!/bin/bash

# Script : permute.sh par Yannou90
# Utilisation : /chemin/vers/permute.sh <NBR de mot> <NBR de charactere minimum par mot> <NBR de charactere maximum par mot> /chemin/vers/dico.txt
# Fichier de sortie : dico.txt dans le répertoire du dictionnare utilisé

FILE="$4"
DIR="${FILE%/*}"
SEQ="$1"
LONGMIN="$2"
LONGMAX="$3"
NUM="1"
DICO="dico.txt"
NEW="working.txt"
TMP="tmp.txt"

cd "$DIR"

rm "$DICO"
pw-inspector -m "$LONGMIN" -M "$LONGMAX" -i "$FILE" | sort -u > "$DICO"
cp "$DICO" "$NEW"

while [[ ! "$NUM" = "$SEQ" ]]
do
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			grep -v "$WORD " "$NEW" | sed -e "s/^/$WORD /g"
		fi
	done < "$DICO" >> "$TMP"
	mv -f  "$TMP"  "$NEW"
	(( NUM++ ))
done

mv -f "$NEW" "$DICO"
		
exit $?

Dernière modification par Yannou90 (Le 23/01/2013, à 15:45)

Hors ligne

#6 Le 25/01/2013, à 14:03

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Encore un p'tit pour la route :

-le script est commenté
-abandon de pw-inspector pour sed
-gestion des options
-interaction avec l'utilisateur : affichage du nombre de lignes créées et du poid du fichier final ( çà fait peur quand même )
-toutes les permutation sont affiché sur stdout , seul les permutations demandées sont stockées dans le fichier final

permute.sh :

#!/bin/bash

# Script : permute.sh par Yannou90
# Utilisation : /chemin/vers/permute.sh <NBR de mot> <NBR de charactere minimum par mot> <NBR de charactere maximum par mot> /chemin/vers/dico.txt
# Fichier de sortie : dico.txt dans le répertoire du dictionnare utilisé

######################
## On cree les variables de bases ##
######################

OPT_PASS=$1
SEQ="3"
LONGMIN="1"
LONGMAX="4"
NUM="1"
DICO="$(date +%s).txt"
NEW="working.txt"
TMP="tmp.txt"
NBR="1"
FACT="1"
CONV=""

#############
## Le menu d'aide ##
#############

function HELP()
{
	echo -e "\
	
	${0##*/} permet la génération de phrases à partir d'un dictionnaire .
	
	Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire .
	Par exemple pour un dictionnaire composé de 30 mots vous pouvez créer des phrases de 2 à 30 mots .
	Toutes les compositions seront créées sans répétition d'un même mot par phrases .
	
	Utilisation :
	
	${0##*/} -m <MIN_LEIGHT_WORD> -M <MAX_LEIGHT_WORD> -w <NBR_WORD> -i <WORDLIST> -o <FILE>
	
	
	-m
		Longueur minimal du mot du dictionnaire (1 par défaut)
	-M
		Longueur maximal du mot du dictionnaire (4 par défaut)
	-w
		Nombre de mots composant la phrase (3 par défaut)
	-i
		Chemin vers le dictionnaire 
	-o
		Fichier de sortie (du type 123456789.txt par défaut , dans le dossier du dictionnaire initial)
		
		
		
		Attention aux nombres de mots composant le dictionnaire et au choix du nombre de mots par phrase .
		
		Exemple , sur un fichier texte composé de 16 mots de 2 à 8 caratères par mots pour un poid de 70 octets , pour composer des phrases de 5 mots :
		
		$0 -m 2 -M 8 -w 5 -i dico.txt
		
		On obtient 16x15x14x13x12 mots = 524160 phrases pour un fichier en sortie de 5x70x15x14x13x12 octets = 11466000 octets = 11197 kio = 10.9 Mio
		
		C'est à dire :
		
		1) Nombre de phrases :
		
		(nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases
		
		2) Poid du fichier final :
		
		(nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final
		
		Equivalent à :
		
		(nombre de mots) x (poid en octets) x (nombre de lignes - 1 ) ! / (nombre de lignes - nombre de mots) ! = poid final en octets / 1024 = poid final en kio / 1024 = poid final en Mio / 1024 = poid final en Gio
		
		
		
		Exemple d'utilisation :
		
		Créer des phrases de 5 mots dans  sortie.txt basé sur les mots de 2 à 8 caractères de dico.txt :
		
		$0 -m 2 -M 8 -w 5 -i dico.txt -o sortie.txt
		
		Créer des phrases de 3 mots dans  sortie.txt basé sur les mots inférieur à 4 caractères de dico.txt :
		
		$0  -M 4 -w 3 -i dico.txt -o sortie.txt
		
		Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt :
		
		$0  -i dico.txt "
		
	exit 1
}

################
## On parse les options ##
################

while getopts ":m:M:w:i:o:" OPT_PASS
do
	case "$OPT_PASS" in
	m)
		LONGMIN="$OPTARG";;
	M)
		LONGMAX="$OPTARG";;
	w)
		SEQ="$OPTARG";;
	i)
		FILE="$OPTARG"
		DIR="${FILE%/*}";;
	o)
		DICO="$OPTARG";;
	*)
		HELP;;
	esac
done

#################################
## On vérifie qu'un dicionnaire est donné en argument ##
#################################

if [[ ! -e "$FILE" ]]
then
	HELP
fi

#######################################
## On se place dans le dossier contenant le dictionnaire de base ##
#######################################

cd "$DIR"

#####################################
## On trie le dictionnaire en fonction de la longeur des mots ##
#####################################

LONGMAX="$(( LONGMAX +1 ))"
sed   "/^.\{$LONGMIN\}/!d; /^.\{$LONGMAX\}/d" "$FILE" | sort -u > "$DICO"

##################################
## On reccupere le nombre de mots du dictionnaire trié ##
##################################

LIGNE="$(wc -l "$DICO" | cut -d' ' -f1)"
MULTIPLI="$LIGNE"

#############################################################
## Si le nombre de mots par phrases à créer est supérieur au nombre de mot du dictionnaire , on quitte ##
#############################################################

if [[ "$LIGNE" -lt "$SEQ" ]]
then
	echo "Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire :
	Nombre de lignes du dictionnaire : $LIGNE
	Nombre de mots par phrase :$SEQ "
	exit 1
fi

##########################################################################
## (nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases ##
##########################################################################

while [[ "$NBR" != "$SEQ" ]]
do
	(( NBR ++ ))
	MULTIPLI="$(( MULTIPLI - 1 ))"
	FACT="$(( FACT*MULTIPLI ))"
done

################################################################################
## (nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final ##
################################################################################

PHRASE="$(( LIGNE*FACT ))"
POID="$(stat -c %s "$DICO")"
TOTAL="$(( POID*FACT*SEQ ))"

##################################################
## On invite l'utilisateur à choisir si oui ou non il souhaite exploser son disque dur :) ##
##################################################

echo "\
Nombre de phrase générées : $PHRASE
Poid du fichier de sortie : $TOTAL octets"

##########################
## Conversion octets -> kio -> Mio -> Gio ##
##########################

if [[ "$TOTAL" -gt "1024" ]]
then
	KCONV="$(( TOTAL/1024 ))"
	KEXT="kio"
	echo "Soit $KCONV $KEXT"
fi
if [[ "$TOTAL" -gt "1048576" ]]
then
	MCONV="$(( TOTAL/1048576 ))"
	MEXT="Mio"
	echo "Soit $MCONV $MEXT"
fi
if [[ "$TOTAL" -gt "1073741824" ]]
then
	GCONV="$(( TOTAL/1073741824 ))"
	GEXT="Gio"
	echo "Soit $GCONV $GEXT"
fi

echo "Souhaitez vous poursuivre ?[y/n]"
read REPONSE

##############
## On lance la bête ##
##############

case "$REPONSE" in
	y)
	cp "$DICO" "$NEW"
	while [[ ! "$NUM" = "$SEQ" ]]
	do
		while read WORD
		do
			if [[ -n "$WORD" ]]
			then
				grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
			fi
		done < "$DICO" | tee -a "$TMP"
		mv -f  "$TMP"  "$NEW"
		(( NUM++ ))
	done
	
	mv -f "$NEW" "$DICO";;
	n)
		echo "On quitte"
		rm "$DICO"
		exit 0;;
	*)
		echo "Choix invalide , on quitte ."
		rm "$DICO"
		exit 1;;
esac
		
exit 0

Hors ligne

#7 Le 26/01/2013, à 14:23

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Bon ben apparement cela n'interresse personne , je persiste , si si , je persiste !

News : choix du mode de sortie , option -q (QUICK-SETTING)

#!/bin/bash

#Mainteneur : Yannou90
#
#Logiciel : permute.sh
#
#Dépendances : bash , sed
#
#Date : 26.01.2013
#
#Description : créer des passphrases de longueurs définis par l'utilisateur en fonction d'un dictionnaire
#
#Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les termes
#de la Licence Publique Générale GNU publiée par la Free Software Foundation
#(version 2 ou bien toute autre version ultérieure choisie par vous).
#
#Ce programme est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE,
#ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation
# dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus
#de détails.
#
#Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même temps
#que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis.
#
# Script : permute.sh par Yannou90
# Utilisation : /chemin/vers/permute.sh <NBR de mot> <NBR de charactere minimum par mot> <NBR de charactere maximum par mot> /chemin/vers/dico.txt

######################
## On cree les variables de bases ##
######################

OPT_PASS=$1
SEQ="3"
LONGMIN="1"
LONGMAX="4"
NUM="1"
DICO="$(date +%s).txt"
NEW="working.txt"
TMP="tmp.txt"
NBR="1"
FACT="1"
CONV=""
VITESSE="0"

#############
## Le menu d'aide ##
#############

function HELP()
{
	echo -e "\
	
	${0##*/} permet la génération de phrases à partir d'un dictionnaire .
	
	Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire .
	Par exemple pour un dictionnaire composé de 30 mots vous pouvez créer des phrases de 2 à 30 mots .
	Toutes les compositions seront créées sans répétition d'un même mot par phrases .
	
	Utilisation :
	
	${0##*/} -[m:M:w:i:o:q:] <ARGUMENT> -Nh
	
	${0##*/} -q <QUICK_SETTING> -m <MIN_LEIGHT_WORD> -M <MAX_LEIGHT_WORD> -w <NBR_WORD> -i <WORDLIST> -o <FILE>
	${0##*/} -i <WORDLIST> -o <FILE>
	${0##*/} -h
	
	
	-m <MIN_LEIGHT_WORD>
		Longueur minimal du mot du dictionnaire (MIN_LEIGHT_WORD=1 par défaut)
	-M <MAX_LEIGHT_WORD>
		Longueur maximal du mot du dictionnaire (MAX_LEIGHT_WORD=4 par défaut)
	-w <NBR_WORD>
		Nombre de mots composant la phrase (NBR_WORD=3 par défaut)
	-i <WORDLIST>
		Chemin vers le dictionnaire 
	-o <FILE>
		Fichier de sortie (FILE=\"\$(date +%s).txt\") du type 1234567890.txt par défaut , dans le dossier du dictionnaire)		
	-q <QUICK_SETTING>
		Mode de sortie : 0 = très rapide mais pas de sortie sur stdout ; 1 = lent mais toutes les combinaisons de 2 à <NBR_WORD> ( option -w <NBR_WORD> ) sont affichées (QUICK_SETTING=0 par défaut)
	-h
		Affiche ce message
		
		
		
		Attention aux nombres de mots composant le dictionnaire et au choix du nombre de mots par phrase .
		
		Exemple , sur un fichier texte composé de 16 mots de 2 à 8 caratères par mots pour un poid de 70 octets , pour composer des phrases de 5 mots :
		
		$0 -m 2 -M 8 -w 5 -i dico.txt
		
		On obtient 16x15x14x13x12 mots = 524160 phrases pour un fichier en sortie de 5x70x15x14x13x12 octets = 11466000 octets = 11197 kio = 10.9 Mio
		
		C'est à dire :
		
		1) Nombre de phrases :
		
		(nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases
		
		2) Poid du fichier final :
		
		(nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final
		
		Equivalent à :
		
		(nombre de mots) x (poid en octets) x (nombre de lignes - 1 ) ! / (nombre de lignes - nombre de mots) ! = poid final en octets / 1024 = poid final en kio / 1024 = poid final en Mio / 1024 = poid final en Gio
		
		
		
		Exemple d'utilisation :
		
		Créer des phrases de 5 mots dans  sortie.txt basé sur les mots de 2 à 8 caractères de dico.txt :
		
		$0 -m 2 -M 8 -w 5 -i dico.txt -o sortie.txt
		
		Créer des phrases de 3 mots dans  sortie.txt basé sur les mots inférieur à 4 caractères de dico.txt :
		
		$0  -M 4 -w 3 -i dico.txt -o sortie.txt
		
		Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt :
		
		$0  -i dico.txt "
}

################
# Pas de sortie standard #
################

function PERMQUICK()
{
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
		fi
	done < "$DICO" > "$TMP"
}

############
# Sortie standard #
############

function PERMTEE()
{
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
		fi
	done < "$DICO" | tee -a "$TMP"
}

###########
# Mode QUICK #
###########

function PERMUTE()
{
	while [[ ! "$NUM" = "$SEQ" ]]
	do
		if [[ "$1" = "0" ]]
		then
			PERMQUICK
		else
			PERMTEE
		fi
		mv -f  "$TMP"  "$NEW"
		(( NUM++ ))
	done
	
	mv -f "$NEW" "$DICO"
}

################
## On parse les options ##
################

while getopts ":m:M:w:i:o:q:h" OPT_PASS
do
	case "$OPT_PASS" in
	m)
		LONGMIN="$OPTARG";;
	M)
		LONGMAX="$OPTARG";;
	w)
		SEQ="$OPTARG";;
	i)
		FILE="$OPTARG"
		DIR="${FILE%/*}";;
	o)
		DICO="$OPTARG";;
	q)
		VITESSE="$OPTARG";;
	h)
		HELP
		exit 0;;
	*)
		HELP
		exit 1;;
	esac
done

#################################
## On vérifie qu'un dicionnaire est donné en argument ##
#################################

if [[ ! -e "$FILE" ]]
then
	HELP
fi

#######################################
## On se place dans le dossier contenant le dictionnaire de base ##
#######################################

cd "$DIR"

#####################################
## On trie le dictionnaire en fonction de la longeur des mots ##
#####################################

LONGMAX="$(( LONGMAX +1 ))"
sed   "/^.\{$LONGMIN\}/!d; /^.\{$LONGMAX\}/d" "$FILE" | sort -u > "$DICO"

##################################
## On reccupere le nombre de mots du dictionnaire trié ##
##################################

LIGNE="$(wc -l "$DICO" | cut -d' ' -f1)"
MULTIPLI="$LIGNE"

#############################################################
## Si le nombre de mots par phrases à créer est supérieur au nombre de mot du dictionnaire , on quitte ##
#############################################################

if [[ "$LIGNE" -lt "$SEQ" ]]
then
	echo "Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire :
	Nombre de lignes du dictionnaire : $LIGNE
	Nombre de mots par phrase :$SEQ "
	exit 1
fi

##########################################################################
## (nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases ##
##########################################################################

while [[ "$NBR" != "$SEQ" ]]
do
	(( NBR ++ ))
	MULTIPLI="$(( MULTIPLI - 1 ))"
	FACT="$(( FACT*MULTIPLI ))"
done

################################################################################
## (nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final ##
################################################################################

PHRASE="$(( LIGNE*FACT ))"
POID="$(stat -c %s "$DICO")"
TOTAL="$(( POID*FACT*SEQ ))"

##################################################
## On invite l'utilisateur à choisir si oui ou non il souhaite exploser son disque dur :) ##
##################################################

echo "\
Nombre de phrase générées : $PHRASE
Poid du fichier de sortie : $TOTAL octets"

##########################
## Conversion octets -> kio -> Mio -> Gio ##
##########################

if [[ "$TOTAL" -gt "1024" ]]
then
	KCONV="$(( TOTAL/1024 ))"
	KEXT="kio"
	echo "Soit $KCONV $KEXT"
fi
if [[ "$TOTAL" -gt "1048576" ]]
then
	MCONV="$(( TOTAL/1048576 ))"
	MEXT="Mio"
	echo "Soit $MCONV $MEXT"
fi
if [[ "$TOTAL" -gt "1073741824" ]]
then
	GCONV="$(( TOTAL/1073741824 ))"
	GEXT="Gio"
	echo "Soit $GCONV $GEXT"
fi

echo "Souhaitez vous poursuivre ?[y/n]"
read REPONSE

##############
## On lance la bête ##
##############

case "$REPONSE" in
	y) 
	cp "$DICO" "$NEW"
		PERMUTE "$VITESSE";;
	n)
		echo "On quitte"
		rm "$DICO"
		exit 0;;
	*)
		echo "Choix invalide , on quitte ."
		rm "$DICO"
		exit 1;;
esac
		
exit 0

Dernière modification par Yannou90 (Le 26/01/2013, à 15:21)

Hors ligne

#8 Le 26/01/2013, à 17:59

nicolas66

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Un truc qui me choque dans ton script c'est le "franglais". Ecris soit en anglais soit en français mais pas les deux wink


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#9 Le 26/01/2013, à 18:10

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

C'est vrais , je ne fais même plus attention hmm
Je vais mettre à jour

Hors ligne

#10 Le 26/01/2013, à 21:19

nicolas66

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Ca n'est pas forcément très important. Tout dépend du public auquel les fichiers que tu produis sont destinés. J'étais dans la même situation il y a quelques années et je code depuis tout le temps en anglais pour avoir une portée plus grande.


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#11 Le 28/01/2013, à 13:18

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Grosse MAJ :

Une bonne partie du code est réécrite :

-modification des options de base
-l'utilisateur peut maintenant limiter le poids de sortie du fichier
-si le poid de sortie supposé est supérieur à la capacitée du disque alors la moitiée "seulement" roll de l'espace libre est utilisé
-ajout de l'option -y supprimant l'interraction avec l'utilisateur
-choix du dossier de sortie
-affichage de statistique sur l'utilisation du script , les prévisions et le fichier de sortie
-passage du mode franglais à francais (@nicolas66 wink )

Enfin voilà quoi , bon je suis toujours désespérement seul mais je continu !!

Le manuel :

	
	permute.sh permet la génération de phrases à partir d'un dictionnaire .
	
	Ce projet à pour but de démontrer l'inutilité du force-brute pur .
	
	Dans le cas du force-brute pur toutes les combinaisons d'une clée supposée sont créé pour retrouver la clée d'origine . Malheureusement , ou plutôt heureusement , pour des clées de type hexadecimal , wpa , ou contenant des caractéres minuscule , majuscule , chiffre et spéciaux , une ETERNITEE serait nécessaire pour découvrir la clée .	
	permute.sh se veut être "intelligent" , car basé sur la méconnaissance des usagers . Il utilise un dictionnaire de mot correspondant à une langue et permet la construction de phrases .	
	Cette méthode réduit considérablement le nombre de clée possible : un usager lambda créera des clées mémorisable , souvent basée sur une association de mots et non sur la sécuritée ; exemple : "Paul et Virginie" , "motdepasse" , .etc ..
	
	Utilisation :
	
	permute.sh -[!:L:w:i:o:p:d:M:G:T] <ARGUMENT> -v -h -F -y
	
	permute.sh  -l <LONG_MIN> -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -o <NOM> -d <DIR> -G 10 -F
	permute.sh -v -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -M 5
	permute.sh -i <DICO> -o <NOM> 
	permute.sh -h
		
	-l <LONG_MIN>
		Longueur minimal du mot du dictionnaire (LONG_MIN=1 par défaut) .
	-L <LONG_MAX>
		Longueur maximal du mot du dictionnaire (LONG_MAX=4 par défaut) .
	-w <NBR_MOTS>
		Nombre de mots composant la phrase (NBR_MOTS=3 par défaut) .
	-i <DICO>
		Chemin vers le dictionnaire 
	-o <NOM>
		Fichier de sortie (NOM="$(date +%s).txt") du type 1234567890.txt par défaut , dans le dossier du dictionnaire) .
	-v
		Mode verbeux , plus lent , toutes les combinaisons de 2 à <NBR_MOTS> sont affichées .
	-F 
		Toutes les combinaisons sont conservées , plus d'espace libre nécessaire .
	-d <DIR>
		Dossier de sortie , par défaut celui contenant le dictionnaire .
	-M <POID>
		Limite le fichier de sortie à <POID> Mio , <POID> étant une valeur numérique sans extension , exemple: -M 10 , limitera à 10Mio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-G <POID>
		Limite le fichier de sortie à <POID> Gio , <POID> étant une valeur numérique sans extension , exemple : -G 10 , limitera à 10Gio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-T <POID>
		Limite le fichier de sortie à <POID> Tio , <POID> étant une valeur numérique sans extension , exemple : -T 10 , limitera à 10Tio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-y
		Pas de confirmation , pas d'interraction avec l'utilisateur .
	-h
		Affiche ce message		
		
	Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire .
	Par exemple pour un dictionnaire composé de 10 mots vous pouvez créer des phrases de 2 à 10 mots .
	Toutes les compositions seront créées sans répétition d'un même mot par phrases .
		
	Attention aux nombres de mots composant le dictionnaire et au choix du nombre de mots par phrase .	
	Exemple , sur un fichier texte composé de 16 mots de 2 à 8 caratères par mots pour un poid de 70 octets , pour composer des phrases de 5 mots :
	
	/media/Perso/Bureau/permute.sh -l 2 -L 8 -w 5 -i dico.txt
	
	On obtient 16x15x14x13x12 mots = 524160 phrases pour un fichier en sortie de 5x70x15x14x13x12 octets = 11466000 octets = 11197 kio = 10.9 Mio	
	C'est à dire :
	
	1) Nombre de phrases :	
	(nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases
	
	2) Poid du fichier final :	
	(nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final	
	Equivalent à :	
	(nombre de mots) x (poid en octets) x (nombre de lignes - 1 ) ! / (nombre de lignes - nombre de mots) ! = poid final en octets / 1024 = poid final en kio / 1024 = poid final en Mio / 1024 = poid final en Gio
	
	Exemple d'utilisation :
	
	Créer des phrases de 5 mots dans  sortie.txt basé sur les mots de 2 à 8 caractères de dico.txt , aucun fichier de plus de 50 Mio ne sera créé:	
	/media/Perso/Bureau/permute.sh -l 2 -L 8 -w 5 -i dico.txt -o sortie.txt -M 50	
	Créer des phrases de 3 mots dans  sortie.txt basé sur les mots inférieur à 4 caractères de dico.txt :	
	/media/Perso/Bureau/permute.sh  -L 4 -w 3 -i dico.txt -o sortie.txt	
	Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt :	
	/media/Perso/Bureau/permute.sh  -i dico.txt 

La version 0.3.3 :

#!/bin/bash

#Mainteneur : Yannou90
#
#Logiciel : permute.sh
#
#Version : 0.3.3
#
#Dépendances : bash , sed , grep , bc
#
#Date : 26.01.2013
#
#Description : créer des passphrases de longueurs définis par l'utilisateur en fonction d'un dictionnaire
#
#Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les termes
#de la Licence Publique Générale GNU publiée par la Free Software Foundation
#(version 2 ou bien toute autre version ultérieure choisie par vous).
#
#Ce programme est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE,
#ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation
# dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus
#de détails.
#
#Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même temps
#que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis.

######################
## On cree les variables de bases ##
######################

OPT_PASS=$1
SEQ="3"
LONGMIN="1"
LONGMAX="4"
NUM="1"
TIME="$(date +%s)"
NEW="working.txt"
TMP="tmp.txt"
DICO="$TIME.txt"
NBR="1"
FACT="1"
CONV=""
VITESSE="0"
FULL="1"
WDIR=""
MEGA="1048576"
GIGA="1073741824"
TERA="1099511627776"
STOP="1"
REPONSE="n"

#############
## Le menu d'aide ##
#############

function HELP()
{
	echo -e "\
	
	${0##*/} permet la génération de phrases à partir d'un dictionnaire .
	
	Ce projet à pour but de démontrer l'inutilité du force-brute pur .
	
	Dans le cas du force-brute pur toutes les combinaisons d'une clée supposée sont créé pour retrouver la clée d'origine . Malheureusement , ou plutôt heureusement , pour des clées de type hexadecimal , wpa , ou contenant des caractéres minuscule , majuscule , chiffre et spéciaux , une ETERNITEE serait nécessaire pour découvrir la clée .	
	${0##*/} se veut être \"intelligent\" , car basé sur la méconnaissance des usagers . Il utilise un dictionnaire de mot correspondant à une langue et permet la construction de phrases .	
	Cette méthode réduit considérablement le nombre de clée possible : un usager lambda créera des clées mémorisable , souvent basée sur une association de mots et non sur la sécuritée ; exemple : \"Paul et Virginie\" , \"motdepasse\" , .etc ..
	
	Utilisation :
	
	${0##*/} -[!:L:w:i:o:p:d:M:G:T] <ARGUMENT> -v -h -F -y
	
	${0##*/}  -l <LONG_MIN> -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -o <NOM> -d <DIR> -G 10 -F
	${0##*/} -v -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -M 5
	${0##*/} -i <DICO> -o <NOM> 
	${0##*/} -h
		
	-l <LONG_MIN>
		Longueur minimal du mot du dictionnaire (LONG_MIN=1 par défaut) .
	-L <LONG_MAX>
		Longueur maximal du mot du dictionnaire (LONG_MAX=4 par défaut) .
	-w <NBR_MOTS>
		Nombre de mots composant la phrase (NBR_MOTS=3 par défaut) .
	-i <DICO>
		Chemin vers le dictionnaire 
	-o <NOM>
		Fichier de sortie (NOM=\"\$(date +%s).txt\") du type 1234567890.txt par défaut , dans le dossier du dictionnaire) .
	-v
		Mode verbeux , plus lent , toutes les combinaisons de 2 à <NBR_MOTS> sont affichées .
	-F 
		Toutes les combinaisons sont conservées , plus d'espace libre nécessaire .
	-d <DIR>
		Dossier de sortie , par défaut celui contenant le dictionnaire .
	-M <POID>
		Limite le fichier de sortie à <POID> Mio , <POID> étant une valeur numérique sans extension , exemple: -M 10 , limitera à 10Mio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-G <POID>
		Limite le fichier de sortie à <POID> Gio , <POID> étant une valeur numérique sans extension , exemple : -G 10 , limitera à 10Gio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-T <POID>
		Limite le fichier de sortie à <POID> Tio , <POID> étant une valeur numérique sans extension , exemple : -T 10 , limitera à 10Tio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-y
		Pas de confirmation , pas d'interraction avec l'utilisateur .
	-h
		Affiche ce message		
		
	Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire .
	Par exemple pour un dictionnaire composé de 10 mots vous pouvez créer des phrases de 2 à 10 mots .
	Toutes les compositions seront créées sans répétition d'un même mot par phrases .
		
	Attention aux nombres de mots composant le dictionnaire et au choix du nombre de mots par phrase .	
	Exemple , sur un fichier texte composé de 16 mots de 2 à 8 caratères par mots pour un poid de 70 octets , pour composer des phrases de 5 mots :
	
	$0 -l 2 -L 8 -w 5 -i dico.txt
	
	On obtient 16x15x14x13x12 mots = 524160 phrases pour un fichier en sortie de 5x70x15x14x13x12 octets = 11466000 octets = 11197 kio = 10.9 Mio	
	C'est à dire :
	
	1) Nombre de phrases :	
	(nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases
	
	2) Poid du fichier final :	
	(nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final	
	Equivalent à :	
	(nombre de mots) x (poid en octets) x (nombre de lignes - 1 ) ! / (nombre de lignes - nombre de mots) ! = poid final en octets / 1024 = poid final en kio / 1024 = poid final en Mio / 1024 = poid final en Gio
	
	Exemple d'utilisation :
	
	Créer des phrases de 5 mots dans  sortie.txt basé sur les mots de 2 à 8 caractères de dico.txt , aucun fichier de plus de 50 Mio ne sera créé:	
	$0 -l 2 -L 8 -w 5 -i dico.txt -o sortie.txt -M 50	
	Créer des phrases de 3 mots dans  sortie.txt basé sur les mots inférieur à 4 caractères de dico.txt :	
	$0  -L 4 -w 3 -i dico.txt -o sortie.txt	
	Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt :	
	$0  -i dico.txt "
}

################
# Pas de sortie standard #
################

function PERMQUICK()
{
	while read WORD
	do
		if [[ -e "stop.txt" ]]
		then
			return 0
		fi
		if [[ -n "$WORD" ]]
		then
			grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
		fi
	done < "$DICO" > "$TMP"
}

############
# Sortie standard #
############

function PERMTEE()
{
	while read WORD
	do
		if [[ -e "stop.txt" ]]
		then
			return 0
		fi
		if [[ -n "$WORD" ]]
		then
			grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
		fi
	done < "$DICO" | tee -a "$TMP"
}

##########
# Permutation #
##########

function PERMUTE()
{
	while [[ ! "$NUM" = "$SEQ" ]]
	do
		if [[ -e "stop.txt" ]]
		then
			break
		fi
		TMP="PASSE_$NUM.txt"
		echo "WORK=$TMP" > limite.txt
		if [[ "$1" = "0" ]]
		then
			PERMQUICK
		else
			PERMTEE
		fi
		if [[ "$FULL" = "1" ]]
		then
			mv -f  "$TMP"  "$NEW"
		else
			NEW="$TMP"
		fi
		(( NUM++ ))
	done
	if [[ "$FULL" = "1" ]]
	then
		mv -f "$NEW" "$DICO"
	fi
}

###########
## Nettoyage ##
###########

function CLEAN()
{
	rm "$DICO"
	if [[ -d "$WDIR" ]]
	then
		rmdir "$WDIR"
	fi
}

########################
## Limiter le poid des fichiers créés ##
########################

function LIMITE()
{
	if [[ "$PALUS" -gt "$TOTAL" ]]
	then
		return 0
	fi
	while true
	do
		sleep "$TIME"
		. limite.txt
		if [[ "$(stat -c %s "$DIR/$WORK")" -gt "$PAPLUS" ]]
		then
			touch stop.txt
			return 0
		fi
	done
}

###########################################
## Convertion octets -> Kio -> Mio -> Gio -> Tio -> Pio -> Eio -> Zio -> Yio ##
###########################################

function CONVERTION()
{
	COUNT="1024"
	
	for i in K M G T P E Z Y
do
	if [[ "$1" -gt "$COUNT" ]]
	then
		CONV="$(bc<<<"scale=2; $1/$COUNT")"
		echo "Soit $CONV $i"io
		COUNT="$(bc<<<"$COUNT*1024")"
	fi
done
}

################################
## Limiter le poid de sortie à 50% de l'espace libre ##
################################

function BADSETTING()
{
	PAPLUS="$(bc<<<"$LIBRE/2")"
	STOP="0"
	TIME="10"
	echo "Limite arbitraire fixée à $PAPLUS octets"
	CONVERTION "$PAPLUS"
}

################
## On parse les options ##
################

while getopts ":l:L:w:i:o:d:M:G:T:vFyh" OPT_PASS
do
	case "$OPT_PASS" in
	l)
		LONGMIN="$OPTARG";;
	L)
		LONGMAX="$OPTARG";;
	w)
		SEQ="$OPTARG";;
	i)
		ORIGINAL="$OPTARG"
		DIR="${ORIGINAL%/*}";;
	o)
		DICO="$OPTARG";;
	v)
		VITESSE="$OPTARG";;
	F)
		FULL="$OPTARG";;
	d)
		WDIR="$OPTARG"
		mkdir -p "$WDIR"
		DIR="$WDIR";;
	M)
		PAPLUS="$(bc<<<"$OPTARG*$MEGA")"
		TIME="0.1"
		STOP="0";;
	G)
		PAPLUS="$(bc<<<"$OPTARG*$GIGA")"
		TIME="1"
		STOP="0";;
	T)
		PAPLUS="$(bc<<<"$OPTARG*$TERA")"
		TIME="10"
		STOP="0";;
	y)
		REPONSE="y";;
	h)
		HELP
		exit 0;;
	*)
		HELP
		exit 1;;
	esac
done

#################################
## On vérifie qu'un dicionnaire est donné en argument ##
#################################

if [[ ! -e "$ORIGINAL" ]]
then
	HELP
	exit 1
fi

##########################
## On se place dans le dossier de travail ##
##########################

cd "$DIR"

#####################################
## On trie le dictionnaire en fonction de la longeur des mots ##
#####################################

LONGX="$(bc<<<"$LONGMAX +1")"
sed   "/^.\{$LONGMIN\}/!d; /^.\{$LONGX\}/d" "$ORIGINAL" | sort -u > "$DICO"

##################################
## On reccupere le nombre de mots du dictionnaire trié ##
##################################

LIGNE="$(wc -l "$DICO" | cut -d' ' -f1)"
MULTIPLI="$LIGNE"

#############################################################
## Si le nombre de mots par phrases à créer est supérieur au nombre de mot du dictionnaire , on quitte ##
#############################################################

if [[ "$LIGNE" -lt "$SEQ" ]]
then
	echo "Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire :
	Nombre de lignes du dictionnaire : $LIGNE
	Nombre de mots par phrase :$SEQ "
	exit 1
fi

##########################################################################
## (nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases ##
##########################################################################

while [[ "$NBR" != "$SEQ" ]]
do
	(( NBR ++ ))
	MULTIPLI="$(bc<<<"$MULTIPLI - 1")"
	FACT="$(bc<<<"$FACT*$MULTIPLI")"
done

################################################################################
## (nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final ##
################################################################################

PHRASE="$(bc<<<"$LIGNE*$FACT")"
POID="$(stat -c %s "$DICO")"
TOTAL="$(bc<<<"$POID*$FACT*$SEQ")"

##################################################
## On invite l'utilisateur à choisir si oui ou non il souhaite exploser son disque dur :) ##
##################################################

echo "\
Nombre de ligne du dictionnaire : $LIGNE
Longueur minimal des mots : $LONGMIN
Longueur maximal des mots : $LONGMAX
Nombre de mots par phrase : $SEQ
Nombre de phrases à générées : $PHRASE
Poid estimé du fichier de sortie : $TOTAL octets"
CONVERTION "$TOTAL"

LIBRE="$(bc<<<"$(df "$DICO" | grep dev | awk '{ print $4 }')*1024")"

if [[ "$STOP" = "0" ]]
then
	echo "Limité par l'utilisateur à $PAPLUS octets"
	CONVERTION "$PAPLUS"
	if [[ "$PAPLUS"  -gt "$LIBRE" ]]
	then
		echo "La limite imposée est supérieure à l'espace libre disponible !"
		BADSETTING
	fi
else
	if [[ "$TOTAL" -gt "$LIBRE" ]]
	then
		BADSETTING
	fi
fi

if [[ "$REPONSE" = "n" ]]
then
	echo "Souhaitez vous poursuivre ?[y/n]"
	read REPONSE
else
	echo "Exécution sans confirmation"
	sleep 3
fi

##############
## On lance la bête ##
##############

case "$REPONSE" in
	y) 
		cp "$DICO" "$NEW"
		if [[ "$STOP" = "0" ]]
		then
			sleep 1
			LIMITE &
		fi
		PERMUTE "$VITESSE"
		if [[ "$STOP" = "0" ]]
		then
			rm stop.txt limite.txt
		fi;;
	n)
		echo "On quitte"
		CLEAN
		exit 0;;
	*)
		echo "Choix invalide , on quitte ."
		CLEAN
		exit 1;;
esac

PHRASE="$(wc -l "$DICO" | cut -d' ' -f1)"
TOTAL="$(stat -c %s "$DICO")"
echo "\
Fichier de sortie : $DIR/$DICO
Nombre de phrases réellements générées : $PHRASE
Poid exacte du fichier de sortie : $TOTAL octets"

CONVERTION "$TOTAL"
		
exit 0

Hors ligne

#12 Le 28/01/2013, à 17:21

nicolas66

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

-passage du mode franglais à francais

Pas complètement. Tu devrai passer tout en anglais (y compris les commentaires). C'est un bon exercice smile


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#13 Le 28/01/2013, à 17:27

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Là je vois pas ??
working.txt ??
Les noms de variables??

Hors ligne

#14 Le 28/01/2013, à 17:37

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Je penses que tu parles des variables et fonctions mais j'étais parti comme "çà" dirons nous et c'est vrais que je ne fais jamais attention à celà , le but pour moi étant de me comprendre .
Apres si c'es vraiment çà , si quelqu'un veut comprendre le script c'est qu'il à déjà de bonnes bases , pas que mon script soit super évolué mais que l'on peut vite se perdre , si il a ces bases quelques soit le nom données aux variables ou fonction cela ne devrait pas le perturber .

Si c'est vraiment le fond , je comprends , mon script n'est pas réellement francisé , mais là çà va être dur pour moi , je passe mon temps sur tout type de forum , à 99% en anglais !!
J'ai donc appris à lire et scripter comme celà , c'est bête , mais tout en français ça va pas être facile !

Hors ligne

#15 Le 29/01/2013, à 19:30

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Re

MAJ : version 0.3.4

-corrections de quelques bugs(sss) et coquilles(sss)
-réécriture d'une bonne partie du script
-optimisation des fonctions
-divers test ajoutés
-support de la compression ( option -C) permettant de compressé à la volée le fichier créé
-lecture directe des archives ( format 7z , pour le moment) sans décompression

Une bonne mise à jour qui correspond de plus en plus à ce que je cherche , à savoir utiliser un minimum de ressources cpu et d'espace disque
Il est maitenant possible de créé un fichier de phrase plus volumineux que l'espace libre sur le disque .

Attention , ne surtout pas décompresser une archive volumineuse ou tenter de voir son contenu avec une GUI , il est possible que cette archive soit énorme , le script intègre l'option -r pour lire l'archive sans décompression
Je ne saurrais être tenue responsable de tout dommage occasionné à votre systeme d'exploitation

Avec ce mode de compression on préserve jusqu'à 16x l'espace disque utilisé

J'ai également trouvé le moyen de réduire le poid du fichier final de plus de 6135x , oui oui ce n'est pas une blague , la suite au prochain numéros .

Bref , le "man" :

	permute.sh permet la génération de phrases à partir d'un dictionnaire .
	
	Ce projet à pour but de démontrer l'inutilité du force-brute pur .
	
	Dans le cas du force-brute pur toutes les combinaisons d'une clée supposée sont créé pour retrouver la clée d'origine . Malheureusement , ou plutôt heureusement , pour des clées de type hexadecimal , wpa , ou contenant des caractéres minuscule , majuscule , chiffre et spéciaux , une ETERNITEE serait nécessaire pour découvrir la clée .	
	permute.sh se veut être "intelligent" , car basé sur la méconnaissance des usagers . Il utilise un dictionnaire de mot correspondant à une langue et permet la construction de phrases .	
	Cette méthode réduit considérablement le nombre de clée possible : un usager lambda créera des clées mémorisable , souvent basée sur une association de mots et non sur la sécuritée ; exemple : "Paul et Virginie" , "motdepasse" , .etc ..
	
	Utilisation :
	
	permute.sh -[!:L:w:i:p:d:r:M:G:T] <ARGUMENT> -v -h -F -y -C
	
	permute.sh  -l <LONG_MIN> -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -d <DIR> -G 10 -F -C
	permute.sh -v -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -M 5
	permute.sh -i <DICO> 
	permute.sh -r <ARCHIVE>
	permute.sh -h
		
	-l <LONG_MIN>
		Longueur minimal du mot du dictionnaire (LONG_MIN=1 par défaut) .
	-L <LONG_MAX>
		Longueur maximal du mot du dictionnaire (LONG_MAX=4 par défaut) .
	-w <NBR_MOTS>
		Nombre de mots composant la phrase (NBR_MOTS=3 par défaut) .
	-i <DICO>
		Chemin vers le dictionnaire 
	-v
		Mode verbeux , plus lent , toutes les combinaisons de 2 à <NBR_MOTS> sont affichées .
	-F 
		Toutes les combinaisons sont conservées , plus d'espace libre nécessaire .
	-d <DIR>
		Dossier de sortie , par défaut celui contenant le dictionnaire .
	-M <POID>
		Limite le fichier de sortie à <POID> Mio , <POID> étant une valeur numérique sans extension , exemple: -M 10 , limitera à 10Mio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-G <POID>
		Limite le fichier de sortie à <POID> Gio , <POID> étant une valeur numérique sans extension , exemple : -G 10 , limitera à 10Gio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-T <POID>
		Limite le fichier de sortie à <POID> Tio , <POID> étant une valeur numérique sans extension , exemple : -T 10 , limitera à 10Tio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-r <ARCHIVE>
		Permet de lire sur la sortie standard le contenu d'une archive au format 7z créé avec permute.sh
	-y
		Pas de confirmation , pas d'interraction avec l'utilisateur .
	-C
		Mode compression : les données sont directement compressée , le mode verbeux n'est pas compatible .
	-h
		Affiche ce message		
		
	Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire .
	Par exemple pour un dictionnaire composé de 10 mots vous pouvez créer des phrases de 2 à 10 mots .
	Toutes les compositions seront créées sans répétition d'un même mot par phrases .
		
	Attention aux nombres de mots composant le dictionnaire et au choix du nombre de mots par phrase .	
	Exemple , sur un fichier texte composé de 16 mots de 2 à 8 caratères par mots pour un poid de 70 octets , pour composer des phrases de 5 mots :
	
	/media/Perso/Bureau/permute.sh -l 2 -L 8 -w 5 -i dico.txt
	
	On obtient 16x15x14x13x12 mots = 524160 phrases pour un fichier en sortie de 5x70x15x14x13x12 octets = 11466000 octets = 11197 kio = 10.9 Mio	
	C'est à dire :
	
	1) Nombre de phrases :	
	(nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases
	
	2) Poid du fichier final :	
	(nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final	
	Equivalent à :	
	(nombre de mots) x (poid en octets) x (nombre de lignes - 1 ) ! / (nombre de lignes - nombre de mots) ! = poid final en octets / 1024 = poid final en kio / 1024 = poid final en Mio / 1024 = poid final en Gio
	
	Exemple d'utilisation :
	
	Créer des phrases de 5 mots basé sur les mots de 2 à 8 caractères de dico.txt , aucun fichier de plus de 50 Mio ne sera créé , toutes les combinaisons de 1 à 5 mots sont conservées , les fichiers sont compressés au format 7z :	
	/media/Perso/Bureau/permute.sh -l 2 -L 8 -w 5 -i dico.txt -M 50 -C -F
	Créer des phrases de 3 mots basé sur les mots inférieur à 4 caractères de dico.txt , aucunes confirmation n'est nécessaire :	
	/media/Perso/Bureau/permute.sh  -L 4 -w 3 -i dico.txt -y
	Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt , toutes les combinaisons sont affichées sur la sortie standars :	
	/media/Perso/Bureau/permute.sh  -i dico.txt -v 
	Lire une archive créée avec permute.sh :
	/media/Perso/Bureau/permute.sh  -r 1234567890.7z

Le script :

#!/bin/bash

#Mainteneur : Yannou90
#
#Logiciel : permute.sh
#
#Version : 0.3.4
#
#Dépendances : 7z
#
#Date : 29.01.2013
#
#Description : créer des passphrases de longueurs définis par l'utilisateur en fonction d'un dictionnaire
#
#Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les termes
#de la Licence Publique Générale GNU publiée par la Free Software Foundation
#(version 2 ou bien toute autre version ultérieure choisie par vous).
#
#Ce programme est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE,
#ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation
# dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus
#de détails.
#
#Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même temps
#que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis.

######################
## On cree les variables de bases ##
######################

OPT_PASS=$1
SEQ="3"
LONGMIN="1"
LONGMAX="4"
NUM="1"
TIME="$(date +%s)"
NEW="${TIME}_PASSE_1.txt"
TMP="${TIME}_tmp.txt"
DICO="${TIME}_DICO.txt"
STOPTXT="${TIME}_stop.txt"
KPID="$TIME.pid"
TIMING="0.1"
NBR="1"
FACT="1"
CONV=""
VITESSE="0"
FULL="1"
WDIR=""
MEGA="1048576"
GIGA="1073741824"
TERA="1099511627776"
STOP="1"
REPONSE="n"
COMPRESSE="1"


#############
## Le menu d'aide ##
#############

function HELP()
{
	echo -e "\
	
	${0##*/} permet la génération de phrases à partir d'un dictionnaire .
	
	Ce projet à pour but de démontrer l'inutilité du force-brute pur .
	
	Dans le cas du force-brute pur toutes les combinaisons d'une clée supposée sont créé pour retrouver la clée d'origine . Malheureusement , ou plutôt heureusement , pour des clées de type hexadecimal , wpa , ou contenant des caractéres minuscule , majuscule , chiffre et spéciaux , une ETERNITEE serait nécessaire pour découvrir la clée .	
	${0##*/} se veut être \"intelligent\" , car basé sur la méconnaissance des usagers . Il utilise un dictionnaire de mot correspondant à une langue et permet la construction de phrases .	
	Cette méthode réduit considérablement le nombre de clée possible : un usager lambda créera des clées mémorisable , souvent basée sur une association de mots et non sur la sécuritée ; exemple : \"Paul et Virginie\" , \"motdepasse\" , .etc ..
	
	Utilisation :
	
	${0##*/} -[!:L:w:i:p:d:r:M:G:T] <ARGUMENT> -v -h -F -y -C
	
	${0##*/}  -l <LONG_MIN> -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -d <DIR> -G 10 -F -C
	${0##*/} -v -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -M 5
	${0##*/} -i <DICO> 
	${0##*/} -r <ARCHIVE>
	${0##*/} -h
		
	-l <LONG_MIN>
		Longueur minimal du mot du dictionnaire (LONG_MIN=1 par défaut) .
	-L <LONG_MAX>
		Longueur maximal du mot du dictionnaire (LONG_MAX=4 par défaut) .
	-w <NBR_MOTS>
		Nombre de mots composant la phrase (NBR_MOTS=3 par défaut) .
	-i <DICO>
		Chemin vers le dictionnaire 
	-v
		Mode verbeux , plus lent , toutes les combinaisons de 2 à <NBR_MOTS> sont affichées .
	-F 
		Toutes les combinaisons sont conservées , plus d'espace libre nécessaire .
	-d <DIR>
		Dossier de sortie , par défaut celui contenant le dictionnaire .
	-M <POID>
		Limite le fichier de sortie à <POID> Mio , <POID> étant une valeur numérique sans extension , exemple: -M 10 , limitera à 10Mio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-G <POID>
		Limite le fichier de sortie à <POID> Gio , <POID> étant une valeur numérique sans extension , exemple : -G 10 , limitera à 10Gio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-T <POID>
		Limite le fichier de sortie à <POID> Tio , <POID> étant une valeur numérique sans extension , exemple : -T 10 , limitera à 10Tio . Par défaut une limite arbitraire est fixée à 50% de l'espace disponible .
	-r <ARCHIVE>
		Permet de lire sur la sortie standard le contenu d'une archive au format 7z créé avec ${0##*/}
	-y
		Pas de confirmation , pas d'interraction avec l'utilisateur .
	-C
		Mode compression : les données sont directement compressée , le mode verbeux n'est pas compatible .
	-h
		Affiche ce message		
		
	Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire .
	Par exemple pour un dictionnaire composé de 10 mots vous pouvez créer des phrases de 2 à 10 mots .
	Toutes les compositions seront créées sans répétition d'un même mot par phrases .
		
	Attention aux nombres de mots composant le dictionnaire et au choix du nombre de mots par phrase .	
	Exemple , sur un fichier texte composé de 16 mots de 2 à 8 caratères par mots pour un poid de 70 octets , pour composer des phrases de 5 mots :
	
	$0 -l 2 -L 8 -w 5 -i dico.txt
	
	On obtient 16x15x14x13x12 mots = 524160 phrases pour un fichier en sortie de 5x70x15x14x13x12 octets = 11466000 octets = 11197 kio = 10.9 Mio	
	C'est à dire :
	
	1) Nombre de phrases :	
	(nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases
	
	2) Poid du fichier final :	
	(nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final	
	Equivalent à :	
	(nombre de mots) x (poid en octets) x (nombre de lignes - 1 ) ! / (nombre de lignes - nombre de mots) ! = poid final en octets / 1024 = poid final en kio / 1024 = poid final en Mio / 1024 = poid final en Gio
	
	Exemple d'utilisation :
	
	Créer des phrases de 5 mots basé sur les mots de 2 à 8 caractères de dico.txt , aucun fichier de plus de 50 Mio ne sera créé , toutes les combinaisons de 1 à 5 mots sont conservées , les fichiers sont compressés au format 7z :	
	$0 -l 2 -L 8 -w 5 -i dico.txt -M 50 -C -F
	Créer des phrases de 3 mots basé sur les mots inférieur à 4 caractères de dico.txt , aucunes confirmation n'est nécessaire :	
	$0  -L 4 -w 3 -i dico.txt -y
	Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt , toutes les combinaisons sont affichées sur la sortie standars :	
	$0  -i dico.txt -v 
	Lire une archive créée avec ${0##*/} :
	$0  -r 1234567890.7z"
}

##################
## Pas de sortie standard ##
##################

function PERMQUICK()
{
	TMP="${TIME}_PASSE_${PASSE}.txt"
	
	while read WORD
	do
		if [[ -e "$STOPTXT" ]]
		then
			break
		fi
		if [[ -n "$WORD" ]]
		then
			grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g" &
			PID="$!"
			echo -e "WORK=\"$TMP\"\nPID=\"$PID\"" > "$KPID"
			wait "$PID" &>/dev/null
		fi
	done < "$DICO" > "$TMP"
}

##############
## Sortie standard ##
##############

function PERMTEE()
{
	TMP="${TIME}_PASSE_${PASSE}.txt"
	
	while read WORD
	do
		if [[ -e "$STOPTXT" ]]
		then
			break
		fi
		if [[ -n "$WORD" ]]
		then
			grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g" &
			PID="$!"
			echo -e "WORK=\"$TMP\"\nPID=\"$PID\"" > "$KPID"
			wait "$PID" &>/dev/null
		fi
	done < "$DICO" | tee -a "$TMP"
}

############
## Compression ##
############

function PERMX()
{	
	TMP="${TIME}_PASSE_${PASSE}.7z"
	
	while read WORD
	do
		if [[ -e "$STOPTXT" ]]
		then
			break
		fi
		if [[ -n "$WORD" ]]
		then
			7z x  "$NEW" -so 2>/dev/null | grep -v -w "$WORD" | sed -e "s/^/$WORD /g" &
			PID="$!"
			echo -e "WORK=\"$TMP\"\nPID=\"$PID\"" > "$KPID"
			wait "$PID" &>/dev/null
		fi
	done < "$DICO" | 7z a "$TMP" -si &>/dev/null
}

############
## Permutation ##
############

function PERMUTE()
{
	if [[ "$1" = "2" ]]
	then
		ARCH="${TIME}_PASSE_1.7z"
		7z a "$ARCH" "$NEW"  &>/dev/null
		rm "$NEW"
		NEW="$ARCH"
	fi
	while [[ ! "$NUM" = "$SEQ" ]]
	do
		PASSE="$(( NUM + 1 ))"
		if [[ -e "$STOPTXT" ]]
		then
			if [[ ! "$1" = "2" ]]
			then
				sed -i '$d' "$TMP"
			fi
			break
		fi
		case $1 in
			0)
				PERMQUICK;;
			1)
				PERMTEE;;
			2)
				PERMX;;
		esac
		if [[ "$FULL" = "1" ]]
		then
			mv -f  "$TMP"  "$NEW"
		else
			NEW="$TMP"
		fi
		(( NUM++ ))
	done
	if [[ "$1" = "2" ]]
	then
		rm "$DICO"
		DICO="${TIME}_DICO.7z"		
	fi
	mv -f "$NEW" "$DICO"
}

###########
## Nettoyage ##
###########

function CLEAN()
{
	rm "$DICO"
	if [[ -d "$WDIR" ]]
	then
		rmdir "$WDIR"
	fi
}

########################
## Limiter le poid des fichiers créés ##
########################

function LIMITE()
{
	
	while true
	do
		sleep "$TIMING"
		. "$KPID"
		if [[ "$(stat -c %s "$DIR/$WORK")" -gt "$PAPLUS" ]]
		then
			touch "$STOPTXT"
			kill "$PID"
			return 0
		fi
	done
}

###########################################
## Convertion octets -> Kio -> Mio -> Gio -> Tio -> Pio -> Eio -> Zio -> Yio ##
###########################################

function CONVERTION()
{
	COUNT="1024"
	
	for i in K M G T P E Z Y
do
	if [[ "$1" -gt "$COUNT" ]]
	then
		CONV="$(bc<<<"scale=2; $1/$COUNT")"
		echo "Soit $CONV $i"io 1>&2
		COUNT="$(bc<<<"$COUNT*1024")"
	fi
done
}

##########################################
## Limiter par défaut le poid du fichier à 50% de l'espace disponible ##
##########################################

function BADSETTING()
{
	PAPLUS="$(bc<<<"$LIBRE/2")"
	STOP="0"
	echo -e "\nLe poid supposé du fichier généré est supérieur à l'espace libre disponible :\nLimite arbitraire fixée à $PAPLUS octets!" 1>&2
	CONVERTION "$PAPLUS"
}


################
## On parse les options ##
################

while getopts ":l:L:w:i:d:r:M:G:T:vFyCh" OPT_PASS
do
	case "$OPT_PASS" in
	l)
		LONGMIN="$OPTARG";;
	L)
		LONGMAX="$OPTARG";;
	w)
		SEQ="$OPTARG";;
	i)
		ORIGINAL="$OPTARG"
		DIR="${ORIGINAL%/*}";;
	v)
		VITESSE="1";;
	F)
		FULL="0";;
	d)
		WDIR="$OPTARG"
		mkdir -p "$WDIR"
		DIR="$WDIR";;
	M)
		PAPLUS="$(bc<<<"$OPTARG*$MEGA")"
		STOP="0";;
	G)
		PAPLUS="$(bc<<<"$OPTARG*$GIGA")"
		STOP="0";;
	T)
		PAPLUS="$(bc<<<"$OPTARG*$TERA")"
		STOP="0";;
	y)
		REPONSE="y";;
	C)
		COMPRESSE="0";;
	r)
		file "$OPTARG" | grep -w "7-zip" && 7z x "$OPTARG" -so  2> /dev/null | cat
		exit 0 ;;
	h)
		HELP
		exit 0;;
	*)
		HELP
		exit 1;;
	esac
done

#################################
## On vérifie qu'un dicionnaire est donné en argument ##
#################################

if [[ ! -e "$ORIGINAL" ]]
then
	echo "Le fichier \"$ORIGINAL\" n'existe pas"
	exit 1
fi

#############################
## Le mode compression désactive le mode verbeux ##
#############################


if [[ "$COMPRESSE" = "0" ]]
then
	if  [[ "$VITESSE" = "1" ]]
	then
		echo -e "Le mode compression et le mode verbeux sont inccompatibles"
	exit 1
	fi
	VITESSE="2"
fi

##########################
## On se place dans le dossier de travail ##
##########################

cd "$DIR"

#####################################
## On trie le dictionnaire en fonction de la longeur des mots ##
#####################################

LONGX="$(bc<<<"$LONGMAX +1")"
sed   "/^.\{$LONGMIN\}/!d; /^.\{$LONGX\}/d" "$ORIGINAL" | sort -u > "$DICO"

##################################
## On reccupere le nombre de mots du dictionnaire trié ##
##################################

LIGNE="$(wc -l "$DICO" | cut -d' ' -f1)"
MULTIPLI="$LIGNE"

#############################################################
## Si le nombre de mots par phrases à créer est supérieur au nombre de mot du dictionnaire , on quitte ##
#############################################################

if [[ "$LIGNE" -lt "$SEQ" ]]
then
	echo "Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots unique composants le dictionnaire :
	Nombre de lignes du dictionnaire : $LIGNE
	Nombre de mots par phrase :$SEQ "
	rm "$DICO"
	exit 1
fi

##########################################################################
## (nombre de lignes) ! / (nombre de ligne - nombre de mots) ! = nombre de phrases sans répétition d'un même mot par phrases ##
##########################################################################

while [[ "$NBR" != "$SEQ" ]]
do
	(( NBR ++ ))
	MULTIPLI="$(bc<<<"$MULTIPLI - 1")"
	FACT="$(bc<<<"$FACT*$MULTIPLI")"
done

################################################################################
## (nombre de mots) x (poid en octets) x (nombre de lignes) ! / ( (nombre de lignes - nombre de mots) ! x (nombre de lignes) ) = poid final ##
################################################################################

PHRASE="$(bc<<<"$LIGNE*$FACT")"
POID="$(stat -c %s "$DICO")"
TOTAL="$(bc<<<"$POID*$FACT*$SEQ")"
if [[ "$VITESSE" = "2" ]]
then
	TOTAL="$(bc<<<"$TOTAL/16")"
fi

##################################################
## On invite l'utilisateur à choisir si oui ou non il souhaite exploser son disque dur :) ##
##################################################

echo "\
Nombre de lignes du dictionnaire : $LIGNE
Longueur minimal des mots : $LONGMIN
Longueur maximal des mots : $LONGMAX
Nombre de mots par phrase : $SEQ
Nombre de phrases à générées : $PHRASE
Poid estimé du fichier de sortie : $TOTAL octets" 1>&2
CONVERTION "$TOTAL"

LIBRE="$(bc<<<"$(df "$DICO" | grep dev | awk '{ print $4 }')*1024")"

########################
## Empécher un dépassement de poid ##
########################

if [[ "$STOP" = "0" ]] 
then
	if [[ "$LIBRE" -lt "$TOTAL" ]]
	then
		if [[ "$PAPLUS" -lt "$LIBRE" ]]
		then
			echo -e "\nPoid du fichier généré limité par l'utilisateur à : $PAPLUS" 1>&2
			CONVERTION "$PAPLUS"
		else
			BADSETTING
		fi
	else
		if [[ "$PAPLUS" -lt "$TOTAL" ]]
		then
			echo -e "\nPoid du fichier généré limité par l'utilisateur à : $PAPLUS" 1>&2
			CONVERTION "$PAPLUS"
		else
			echo -e "\nLa limite imposée est supérieur au poid supposé du fichier à générer : limite désactivée !" 1>&2
			STOP="1"
		fi
	fi
else
	if [[ "$TOTAL" -gt "$LIBRE" ]]
	then
	BADSETTING
	fi
fi
	

if [[ "$REPONSE" = "n" ]]
then
	echo -e "\nSouhaitez vous poursuivre ? [y/n]" 1>&2
	read REPONSE
else
	echo -e "\nExécution sans confirmation" 1>&2
fi

##############
## On lance la bête ##
##############

case "$REPONSE" in
	y) 
		cp "$DICO" "$NEW"
		if [[ "$STOP" = "0" ]]
		then
			sleep 1
			LIMITE &
		fi
		PERMUTE "$VITESSE"
		if [[ "$STOP" = "0" ]]
		then
			rm "$STOPTXT"
		fi
		rm "$KPID";;
	n)
		echo "On quitte"
		CLEAN
		exit 0;;
	*)
		echo "Choix invalide , on quitte ."
		CLEAN
		exit 1;;
esac

TOTAL="$(stat -c %s "$DICO")"

if [[ "$VITESSE" = "2" ]]
then
	if [[ "$TOTAL" -gt "$GIGA" ]]
	then
		echo "\nPoid trop important , les informations sont désactivées !" 1>&2
		exit 0
	fi
	PHRASE="$(7z x "$DICO" -so 2>/dev/null | wc -l | cut -d' ' -f1)"
else
	PHRASE="$(wc -l "$DICO" | cut -d' ' -f1)"
fi

##############################
## Quleques informations sur le fichier produit ##
##############################

echo -e "\n\
Fichier de sortie : $DIR/$DICO
Nombre de phrases réellements générées : $PHRASE
Poid exacte du fichier de sortie : $TOTAL octets" 1>&2

CONVERTION "$TOTAL"
		
exit 0

Dernière modification par Yannou90 (Le 29/01/2013, à 22:29)

Hors ligne

#16 Le 31/01/2013, à 10:06

Feeling97

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

C'est une blague ou c'est pas une blague? Un script comme ça en Bash Oo
Jte respecte Yannou90 x)
Dès ce soir j'installe et je test quand j'aurai trouvé le moyen de réparer Grub


Steam en natif sous Ubuntu
Ordinateur portable Asus K73S avec Ubuntu 12.04.2 LTS en dual boot avec Windows 7 Ultimate Edition et BURG pour le boot.

Hors ligne

#17 Le 02/02/2013, à 16:23

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

MAJ : version 0.4.1

-Corrections de bug sur les comparaisons de nombres
-Optimisation du code (encore beaucoup à faire)
-Compression améliorée (le poid du fichier devient ridicule)
-Choix du nombre de phrases à générer

Bonne mise à jour , les archives obtenu ont un poid ridicules , exemple :

Le dictionnaire original de test , 240 mots , représentant tout les caracteres hexadecimaux :

01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
12
13
14
15
16
17
18
19
1A
1B
1C
1D
1E
1F
20
21
23
24
25
26
27
28
29
2A
2B
2C
2D
2E
2F
30
31
32
34
35
36
37
38
39
3A
3B
3C
3D
3E
3F
40
41
42
43
45
46
47
48
49
4A
4B
4C
4D
4E
4F
50
51
52
53
54
56
57
58
59
5A
5B
5C
5D
5E
5F
60
61
62
63
64
65
67
68
69
6A
6B
6C
6D
6E
6F
70
71
72
73
74
75
76
78
79
7A
7B
7C
7D
7E
7F
80
81
82
83
84
85
86
87
89
8A
8B
8C
8D
8E
8F
90
91
92
93
94
95
96
97
98
9A
9B
9C
9D
9E
9F
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
AB
AC
AD
AE
AF
B0
B1
B2
B3
B4
B5
B6
B7
B8
B9
BA
BC
BD
BE
BF
C0
C1
C2
C3
C4
C5
C6
C7
C8
C9
CA
CB
CD
CE
CF
D0
D1
D2
D3
D4
D5
D6
D7
D8
D9
DA
DB
DC
DE
DF
E0
E1
E2
E3
E4
E5
E6
E7
E8
E9
EA
EB
EC
ED
EF
F0
F1
F2
F3
F4
F5
F6
F7
F8
F9
FA
FB
FC
FD
FE

Génération d'un nouveau dictionnaire composé de 5 mots par phrases , limité à 10 000 000 de phrases , sans doublons , un mot par phrase :

time /media/Perso/Bureau/permute.sh -i/media/Perso/Bureau/double_hexa.txt -L 8 -w 5 -P 10000000  -y
Espace libre disponible : 204618592256 octets
Soit 199822844.00 Kio
Soit 195139.49 Mio
Soit 190.56 Gio

Nombre de lignes du dictionnaire : 240
Longueur minimal des mots : 1
Longueur maximal des mots : 8
Nombre de mots par phrase : 5
Nombre de phrases à générées : 763565765760
Poid du fichier généré : 11453486486400 octets
Soit 11185045396.87 Kio
Soit 10922895.89 Mio
Soit 10666.89 Gio
Soit 10.41 Tio

Nombre de phrases limitées à : 10000000
Poid supposé du fichier généré : 150000000 octets
Soit 146484.37 Kio
Soit 143.05 Mio

Exécution sans confirmation

Fichier de sortie : /media/Perso/Bureau/1359817824_DICO.txt
Poid du fichier produit : 150000000 octets
Soit 146484.37 Kio
Soit 143.05 Mio
Nombre de phrases générées : 10000000

real	0m16.555s
user	0m12.473s
sys	0m2.168s

Resultat : 16s pour généré 10 000 000 phrases de 5 mots , sans doublon pour un poid de 143.05 Mio

La même commande mais pour obtenir une archive ( option -C )

time /media/Perso/Bureau/permute.sh -i/media/Perso/Bureau/double_hexa.txt -L 8 -w 5 -P 10000000  -y -C
Espace libre disponible : 204468588544 octets
Soit 199676356.00 Kio
Soit 194996.44 Mio
Soit 190.42 Gio

Nombre de lignes du dictionnaire : 240
Longueur minimal des mots : 1
Longueur maximal des mots : 8
Nombre de mots par phrase : 5
Nombre de phrases à générées : 763565765760
Poid du fichier généré : 3033232650 octets
Soit 2962141.25 Kio
Soit 2892.71 Mio
Soit 2.82 Gio

Nombre de phrases limitées à : 10000000
Poid supposé du fichier généré : 39724 octets
Soit 38.79 Kio

Exécution sans confirmation

Fichier de sortie : /media/Perso/Bureau/1359818020_DICO.7z
Poid du fichier produit : 16078 octets
Soit 15.70 Kio
Nombre de phrases générées : 10042744

real	0m24.655s
user	0m21.077s
sys	0m5.868s

Cette fois ci : 24 secondes pour générer 10 000 000 de phrases MAIS une archive de 15.70 Kio cool

On se rend compte du potentiel : le fichier non compressé fait 143.05 Mio contre 15.70 Kio pour l'archive :

150000000 octets / 16078 octets = 9329

On obtien un rapport de compression de plus de 9329x

L'aide du logiciel :

	permute.sh permet la génération de phrases à partir d'un dictionnaire , par permutations des mots .
	
	Ce projet à pour but de démontrer l'inutilité du force-brute .
	
	Utilisation :
	
	permute.sh -[!:L:w:i:p:d:r:P:] <ARGUMENT> -v -h -y -C
	
	permute.sh  -l <LONG_MIN> -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -d <DIR> -C -P <NBR_PHRASES>
	permute.sh -v -L <LONG_MAX> -w <NBR_MOTS> -i <DICO>
	permute.sh -i <DICO>  -P 10000
	permute.sh -r <ARCHIVE>
	permute.sh -h
		
	-l <LONG_MIN>
		Longueur minimal du mot du dictionnaire (LONG_MIN=1 par défaut) .
	-L <LONG_MAX>
		Longueur maximal du mot du dictionnaire (LONG_MAX=4 par défaut) .
	-w <NBR_MOTS>
		Nombre de mots composant la phrase (NBR_MOTS=3 par défaut) .
	-i <DICO>
		Chemin vers le dictionnaire 
	-v
		Mode verbeux , plus lent , toutes les combinaisons de 2 à <NBR_MOTS> sont affichées , le mode compression n'est pas compatible .
	-d <DIR>
		Dossier de sortie , par défaut celui contenant le dictionnaire .
	-r <ARCHIVE>
		Permet de lire sur la sortie standard le contenu d'une archive au format 7z créé avec permute.sh
	-y
		Pas de confirmation , pas d'interraction avec l'utilisateur .
	-C
		Mode compression : les données sont directement compressée , le mode verbeux n'est pas compatible .
	-P <NBR_PHRASES>
		Limiter la création de  phrases à <NBR_PHRASES> ( par défaut limité à 1000000 )
	-h
		Affiche ce message		
		
	Exemple d'utilisation :
	
	# Créer des phrases de 5 mots basé sur les mots de 2 à 8 caractères de dico.txt , les fichiers sont compressés au format 7z :
	
	/media/Perso/Bureau/permute.sh -l 2 -L 8 -w 5 -i dico.txt -C 
	
	# Créer des phrases de 3 mots basé sur les mots inférieur à 4 caractères de dico.txt , aucunes confirmation n'est nécessaire :
	
	/media/Perso/Bureau/permute.sh  -L 4 -w 3 -i dico.txt -y
	
	# Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt , limité à 1000000 phrases , toutes les combinaisons sont affichées sur la sortie standars :
	
	/media/Perso/Bureau/permute.sh  -i dico.txt -v
	
	# Lire une archive créée avec permute.sh :
	
	/media/Perso/Bureau/permute.sh  -r 1234567890.7z

La version 0.4.1 :

#!/bin/bash

#Mainteneur : Yannou90
#
#Logiciel : permute.sh
#
#Version : 0.4.1
#
#Dépendances : 7z , bc
#
#Date : 02.02.2013
#
#Description : créer des passphrases de longueurs définis par l'utilisateur en fonction d'un dictionnaire
#
#Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les termes
#de la Licence Publique Générale GNU publiée par la Free Software Foundation
#(version 2 ou bien toute autre version ultérieure choisie par vous).
#
#Ce programme est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE,
#ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation
# dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus
#de détails.
#
#Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même temps
#que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis.

######################
## On cree les variables de bases ##
######################

OPT_PASS=$1
SEQ="3"
LONGMIN="1"
LONGMAX="4"
NUM="1"
TIME="$(date +%s)"
NEW="${TIME}_PASSE_1.txt"
TMP="${TIME}_tmp.txt"
DICO="${TIME}_DICO.txt"
TIMING="0.1"
NBR="1"
FACT="1"
CONV=""
VITESSE="0"
FULL="1"
WDIR=""
REPONSE="n"
COMPRESSE="1"
PHRASES="n"
NBRM="1000000"

#############
## Le menu d'aide ##
#############

function HELP()
{
	echo -e "\
	
	${0##*/} permet la génération de phrases à partir d'un dictionnaire , par permutations des mots .
	
	Ce projet à pour but de démontrer l'inutilité du force-brute .
	
	Utilisation :
	
	${0##*/} -[!:L:w:i:p:d:r:P:] <ARGUMENT> -v -h -y -C
	
	${0##*/}  -l <LONG_MIN> -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -d <DIR> -C -P <NBR_PHRASES>
	${0##*/} -v -L <LONG_MAX> -w <NBR_MOTS> -i <DICO>
	${0##*/} -i <DICO>  -P 10000
	${0##*/} -r <ARCHIVE>
	${0##*/} -h
		
	-l <LONG_MIN>
		Longueur minimal du mot du dictionnaire (LONG_MIN=1 par défaut) .
	-L <LONG_MAX>
		Longueur maximal du mot du dictionnaire (LONG_MAX=4 par défaut) .
	-w <NBR_MOTS>
		Nombre de mots composant la phrase (NBR_MOTS=3 par défaut) .
	-i <DICO>
		Chemin vers le dictionnaire 
	-v
		Mode verbeux , plus lent , toutes les combinaisons de 2 à <NBR_MOTS> sont affichées , le mode compression n'est pas compatible .
	-d <DIR>
		Dossier de sortie , par défaut celui contenant le dictionnaire .
	-r <ARCHIVE>
		Permet de lire sur la sortie standard le contenu d'une archive au format 7z créé avec ${0##*/}
	-y
		Pas de confirmation , pas d'interraction avec l'utilisateur .
	-C
		Mode compression : les données sont directement compressée , le mode verbeux n'est pas compatible .
	-P <NBR_PHRASES>
		Limiter la création de  phrases à <NBR_PHRASES> ( par défaut limité à 1000000 )
	-h
		Affiche ce message		
		
	Exemple d'utilisation :
	
	# Créer des phrases de 5 mots basé sur les mots de 2 à 8 caractères de dico.txt , les fichiers sont compressés au format 7z :
	
	$0 -l 2 -L 8 -w 5 -i dico.txt -C 
	
	# Créer des phrases de 3 mots basé sur les mots inférieur à 4 caractères de dico.txt , aucunes confirmation n'est nécessaire :
	
	$0  -L 4 -w 3 -i dico.txt -y
	
	# Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt , limité à 1000000 phrases , toutes les combinaisons sont affichées sur la sortie standars :
	
	$0  -i dico.txt -v
	
	# Lire une archive créée avec ${0##*/} :
	
	$0  -r 1234567890.7z"
}

##################
## Pas de sortie standard ##
##################

function PERMQUICK()
{
	TMP="${TIME}_PASSE_${PASSE}.txt"
	BOUCLE=""
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
		fi
			(( BOUCLE++ ))
			if [[ "$BOUCLE" = "$MAX" ]]
			then
			return 0
			fi
	done < "$DICO" | head -n "$MAX" > "$TMP"
}

##############
## Sortie standard ##
##############

function PERMTEE()
{
	TMP="${TIME}_PASSE_${PASSE}.txt"
	BOUCLE=""
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			 grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
		fi
		(( BOUCLE++ ))
			if [[ "$BOUCLE" = "$MAX" ]]
			then
			return 0
			fi
	done < "$DICO" | head -n "$MAX" | tee -a "$TMP"
}

############
## Compression ##
############

function PERMX()
{	
	TMP="${TIME}_PASSE_${PASSE}.7z"
	BOUCLE=""
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			7z e  "$NEW" -so 2>/dev/null | grep -v -w "$WORD" | sed -e "s/^/$WORD /g"
		fi
		(( BOUCLE++ ))
			if [[ "$BOUCLE" = "$MAX" ]]
			then
			return 0
			fi
	done < "$DICO" | head -n "$MAX" | 7z a "$TMP" -si &>/dev/null
}

############
## Permutation ##
############

function PERMUTE()
{
	if [[ "$1" = "2" ]]
	then
		ARCH="${TIME}_PASSE_1.7z"
		7z a "$ARCH" "$NEW"  &>/dev/null
		rm "$NEW"
		NEW="$ARCH"
		(( SEQ-- ))
	fi
	while [[ ! "$NUM" = "$SEQ" ]]
	do
		PASSE="$(( NUM + 1 ))"
		if [[ "$PASSE" = "$SEQ" ]]
		then
			if [[ ! "$COMPRESSE" = "0" ]]
			then
			MAX="$NBRM"
			fi
		fi
		case "$1" in
			0)
				PERMQUICK;;
			1)
				PERMTEE;;
			2)
				PERMX;;
		esac
		mv -f  "$TMP"  "$NEW"
		(( NUM++ ))
	done
	if [[ "$1" = "2" ]]
	then
		7z a  "$NEW" "$DICO" &>/dev/null
		rm "$DICO"
		DICO="${TIME}_DICO.7z"
	fi
	mv -f "$NEW" "$DICO"
}

###########
## Nettoyage ##
###########

function CLEAN()
{
	rm "$DICO"
	if [[ -d "$WDIR" ]]
	then
		rmdir "$WDIR"
	fi
}

###########################################
## Convertion octets -> Kio -> Mio -> Gio -> Tio -> Pio -> Eio -> Zio -> Yio ##
###########################################

function CONVERTION()
{
	COUNT="1024"
	
	for i in K M G T P E Z Y
	do
	if COMPARE "$1" "$COUNT"
	then
		CONV="$(bc<<<"scale=2; $1/$COUNT")"
		echo "Soit $CONV $i"io 1>&2
		COUNT="$(bc<<<"$COUNT*1024")"
	else
		return 0
	fi
	done
}

################################################
## Résoudre le probleme des chaines longues dans les comparaisons nnumériques ##
################################################

function COMPARE()
{
	ZERO="$(bc<<<"$1<=$2")"
	return "$ZERO"
}

###################
## Lire une archive ULTRA ##
###################

function READ()
{
	ZIP="$1"
	NOM_ZIP="$(basename "$1")"
	DICT="$(echo "$NOM_ZIP" | cut -d'.' -f1)"
	TXT_DICT="$DICT.txt"
	
	while read WORD
	do
		7z e -so "$ZIP" -- "$DICT" 2>/dev/null | grep -v -w "$WORD" | sed -e "s/^/$WORD /g"
	done <<<"$(7z e -so "$ZIP" -- "$TXT_DICT" 2>/dev/null | cat)"
}

################
## On parse les options ##
################

while getopts ":l:L:w:i:d:r:P:vyCh" OPT_PASS
do
	case "$OPT_PASS" in
	l)
		LONGMIN="$OPTARG";;
	L)
		LONGMAX="$OPTARG";;
	w)
		SEQ="$OPTARG";;
	i)
		ORIGINAL="$OPTARG"
		if [[ ! -e "$ORIGINAL" ]]
		then
			echo "Le fichier n'existe pas"
			exit 1
		fi
		DIR="${ORIGINAL%/*}";;
	v)
		VITESSE="1";;
	d)
		WDIR="$OPTARG"
		mkdir -p "$WDIR"
		DIR="$WDIR";;
	y)
		REPONSE="y";;
	C)
		COMPRESSE="0";;
	r)
		ZIP="$OPTARG"
		if [[ ! -e "$ZIP" ]]
		then
			echo "Le fichier n'existe pas"
			exit 1
		fi
		if [[ "$(file "$OPTARG" | grep -w "7-zip")" = "1" ]]
		then
			echo "Cette archive n'est pas pris en charge"
			exit 1
		fi
		READ "$ZIP"
		exit 0;;
	P)
		NBRM="$OPTARG";;
	h)
		HELP
		exit 0;;
	*)
		HELP
		exit 1;;
	esac
done

#################
## Pas d'options -> help ##
#################

if [[ "$(echo "$@"no)" = "no" ]]
then
	HELP
	exit 1
fi
################################
## Le mode compression désactive le mode verbeux ##
################################


if [[ "$COMPRESSE" = "0" ]]
then
	if  [[ "$VITESSE" = "1" ]]
	then
		echo -e "Le mode compression et le mode verbeux sont inccompatibles"
	exit 1
	fi
	VITESSE="2"
fi

##########################
## On se place dans le dossier de travail ##
##########################

cd "$DIR"

#####################################
## On trie le dictionnaire en fonction de la longeur des mots ##
#####################################

LONGX="$(bc<<<"$LONGMAX +1")"
sed   "/^.\{$LONGMIN\}/!d; /^.\{$LONGX\}/d" "$ORIGINAL" | sort -u | sort -R > "$DICO"

##################################
## On reccupere le nombre de mots du dictionnaire trié ##
##################################

LIGNE="$(wc -l "$DICO" | cut -d' ' -f1)"
MULTIPLI="$LIGNE"

#############################################################
## Si le nombre de mots par phrases à créer est supérieur au nombre de mot du dictionnaire , on quitte ##
#############################################################

if COMPARE   "$SEQ"  "$LIGNE"
then
	echo "Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots composants le dictionnaire :
	Nombre de lignes du dictionnaire : $LIGNE
	Nombre de mots par phrase :$SEQ "
	rm "$DICO"
	exit 1
fi

###########################
## Calcul du poid et du nombre de phrases ##
###########################

PERM="$SEQ"
POID="$(stat -c %s "$DICO")"
MAX="$(bc<<<"($NBRM/($LIGNE-$SEQ))+1")"

while [[ "$NBR" != "$PERM" ]]
do
	(( NBR ++ ))
	MULTIPLI="$(bc<<<"$MULTIPLI - 1")"
	FACT="$(bc<<<"$FACT*$MULTIPLI")"
done

PHRASE="$(bc<<<"$LIGNE*$FACT")"
TOTAL="$(bc<<<"$POID*$FACT*$PERM")"
PTOT="$(bc -l<<<"(($NBRM/$PHRASE)*$TOTAL+1)" | cut -d'.' -f1)"

if [[ "$VITESSE" = "2" ]]
then	
	TOTAL="$(bc<<<"($TOTAL+$POID)/(16*$MULTIPLI)")"
	PTOT="$(bc<<<"($PTOT+$POID)/(16*$MULTIPLI)")"
fi


##################################################
## On invite l'utilisateur à choisir si oui ou non il souhaite exploser son disque dur :) ##
##################################################

LIBRE="$(bc<<<"$(df "$DICO" | grep dev | awk '{ print $4 }')*1024")"
echo "Espace libre disponible : $LIBRE octets"
CONVERTION "$LIBRE"

echo -e "\n\
Nombre de lignes du dictionnaire : $LIGNE
Longueur minimal des mots : $LONGMIN
Longueur maximal des mots : $LONGMAX
Nombre de mots par phrase : $SEQ
Nombre de phrases à générées : $PHRASE
Poid du fichier généré : $TOTAL octets"
CONVERTION "$TOTAL"

echo -e "\n\
Nombre de phrases limitées à : $NBRM
Poid supposé du fichier généré : $PTOT octets"
CONVERTION "$PTOT"

COMPARE "$LIBRE" "$PTOT"

if [[ "$?" = "1" ]]
then
	echo -e "\nVous ne disposez pas de l'espace disque nécessaire !\nVeuillez corriger les options sélectionnées ."
	exit 1
fi

##############
## On lance la bête ##
##############

if [[ "$REPONSE" = "n" ]]
then
	echo -e "\nSouhaitez vous poursuivre ? [y/n]" 1>&2
	read REPONSE
else
	echo -e "\nExécution sans confirmation" 1>&2
fi


case "$REPONSE" in
	y) 
		cp "$DICO" "$NEW"
		PERMUTE "$VITESSE";;
	n)
		echo "On quitte"
		CLEAN
		exit 0;;
	*)
		echo "Choix invalide , on quitte ."
		CLEAN
		exit 1;;
esac

TOTAL="$(stat -c %s "$DICO")"

##############################
## Quelques informations sur le fichier produit ##
##############################

echo -e "\n\
Fichier de sortie : $DIR/$DICO
Poid du fichier produit : $TOTAL octets" 1>&2
CONVERTION "$TOTAL"
if [[ "$VITESSE" = "2" ]]
then
	NBR_PH="$(READ "$DICO" | wc -l | cut -d' ' -f1)"
else
	NBR_PH="$(wc -l "$DICO" | cut -d' ' -f1)"
fi
	echo "Nombre de phrases générées : $NBR_PH" 1>&2
exit 0

Hors ligne

#18 Le 02/02/2013, à 22:03

nicolas66

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Je ne suis pas modérateur mais vu la tournure que ça prend, je serai d'avis de déplacer ton sujet dans le forum "Vos développements libres" ...


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#19 Le 02/02/2013, à 23:25

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Pourquoi deplacer ce topic ?
Pourquoi pas ?!

Je respecte scrupuleusement les regles du forum , à savoir :

-je suis courtois
-le sujet pose une question bien particuliere qui n'a pas de réponses
-j'ai longuement recherché des réponses à mes interrogations , qui sont , je le rappelle si cela n'etait pas très clair : à quoi peut bien servir le brute force , optimiser le brute force pour quoi faire , pourquoi utiliser des mots de passes longs avec minuscules , majuscules , chiffres et caracteres speciaux et comment l'optimiser sans aucuns succes
-optimiser sont mot de passe
-je poste mes recherches et leurs debordements
-licence gnu
-je suis ma ligne et n'en deborde pas : ligne 2 de l'aide de permute.sh:

Ce projet à pour but de démontrer l'inutilité du force-brute .

Çà parait bête mais oui ce logiciel démontre sa propre inutilitée , c'est un drole de concept mais pourquoi pas !

Apres , cela n'interresse personne , c'est vrais !
Mais je suis bien en plein developpement .

Je ne suis agressif en rien et souhaite partager mes interrogations et decouvertes  avec tout le monde !

Enfin bon , si j'ai heurté la sensibilitée de certains je m'en excuse , sinon je suis ouvert au dialogue , j'ai d'ailleur ouvert un topic pour çà : ici

Dernière modification par Yannou90 (Le 02/02/2013, à 23:31)

Hors ligne

#20 Le 03/02/2013, à 13:24

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

@nicolas66
Bon apres reflexion il est vrai que ce topic pourrait être deplacé , mais bon ...

Hors ligne

#21 Le 03/02/2013, à 13:28

Yannou90

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

MAJ : version 4.0.2 :

-correction bug sur calcul du "poid supposé"
-il est maintenant possible de spécifier un séparateur entre les mots ( " " , un espace par defaut , option -s)

le script :

#!/bin/bash

#Mainteneur : Yannou90
#
#Logiciel : permute.sh
#
#Version : 0.4.2
#
#Dépendances : 7z , bc
#
#Date : 03.02.2013
#
#Description : créer des passphrases de longueurs définis par l'utilisateur en fonction d'un dictionnaire
#
#Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les termes
#de la Licence Publique Générale GNU publiée par la Free Software Foundation
#(version 2 ou bien toute autre version ultérieure choisie par vous).
#
#Ce programme est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE,
#ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation
# dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus
#de détails.
#
#Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même temps
#que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis.

######################
## On cree les variables de bases ##
######################

OPT_PASS=$1
SEQ="3"
LONGMIN="1"
LONGMAX="4"
NUM="1"
TIME="$(date +%s)"
NEW="${TIME}_PASSE_1.txt"
TMP="${TIME}_tmp.txt"
DICO="${TIME}_DICO.txt"
TIMING="0.1"
NBR="1"
FACT="1"
CONV=""
VITESSE="0"
FULL="1"
WDIR=""
REPONSE="n"
COMPRESSE="1"
PHRASES="n"
NBRM="1000000"
SEP=" "
VERIF="n"

#############
## Le menu d'aide ##
#############

function HELP()
{
	echo -e "\
	
	${0##*/} permet la génération de phrases à partir d'un dictionnaire , par permutations des mots .
	
	Ce projet à pour but de démontrer l'inutilité du force-brute .
	
	Utilisation :
	
	${0##*/} -[!:L:w:i:p:d:r:P:s:] <ARGUMENT> -v -h -y -C
	
	${0##*/}  -l <LONG_MIN> -L <LONG_MAX> -w <NBR_MOTS> -i <DICO> -d <DIR> -C -P <NBR_PHRASES> -s <SEPARATEUR>
	${0##*/} -v -L <LONG_MAX> -w <NBR_MOTS> -i <DICO>
	${0##*/} -i <DICO>  -P 10000
	${0##*/} -r <ARCHIVE>
	${0##*/} -h
		
	-l <LONG_MIN>
		Longueur minimal du mot du dictionnaire (LONG_MIN=1 par défaut) .
	-L <LONG_MAX>
		Longueur maximal du mot du dictionnaire (LONG_MAX=4 par défaut) .
	-w <NBR_MOTS>
		Nombre de mots composant la phrase (NBR_MOTS=3 par défaut) .
	-i <DICO>
		Chemin vers le dictionnaire 
	-v
		Mode verbeux , plus lent , toutes les combinaisons de 2 à <NBR_MOTS> sont affichées , le mode compression n'est pas compatible .
	-d <DIR>
		Dossier de sortie , par défaut celui contenant le dictionnaire .
	-r <ARCHIVE>
		Permet de lire sur la sortie standard le contenu d'une archive au format 7z créé avec ${0##*/}
	-y
		Pas de confirmation , pas d'interraction avec l'utilisateur .
	-C
		Mode compression : les données sont directement compressée , le mode verbeux n'est pas compatible .
	-P <NBR_PHRASES>
		Limiter la création de  phrases à <NBR_PHRASES> ( par défaut limité à 1000000 )
	-s <SEPARATEUR>
		Utilise <SEPARATEUR> comme séparateur entre chaque mot (SEPARATEUR=" " par défaut) .
	-h
		Affiche ce message		
		
	Exemple d'utilisation :
	
	# Créer 1000000 de phrases de 5 mots basé sur les mots de 2 à 8 caractères de dico.txt , utiliser ':'  comme séparateur , le fichier est compressé au format 7z :
	
	$0 -l 2 -L 8 -w 5 -i dico.txt -C -P 1000000 -s ":"
	
	# Créer des phrases de 3 mots basé sur les mots inférieur à 4 caractères de dico.txt , aucunes confirmation n'est nécessaire :
	
	$0  -L 4 -w 3 -i dico.txt -y
	
	# Créer des phrases de 3 mots dans  123456789.txt basé sur les mots de 1 à 4 caractères de dico.txt , limité à 1000000 phrases , toutes les combinaisons sont affichées sur la sortie standars :
	
	$0  -i dico.txt -v
	
	# Lire une archive créée avec ${0##*/} :
	
	$0  -r 1234567890.7z"
}

##################
## Pas de sortie standard ##
##################

function PERMQUICK()
{
	TMP="${TIME}_PASSE_${PASSE}.txt"
	BOUCLE=""
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			(( BOUCLE++ ))
			if [[ "$NULL" = "sep" ]]
			then
				grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g" | sed -e "s/ /$SEP/g"
			else
				grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
			fi
		fi
		if [[ "$BOUCLE" = "$MAX" ]]
		then
		return 0
		fi
	done < "$DICO" | head -n "$MAX" > "$TMP"
}

##############
## Sortie standard ##
##############

function PERMTEE()
{
	TMP="${TIME}_PASSE_${PASSE}.txt"
	BOUCLE=""
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			(( BOUCLE++ ))
			 if [[ "$NULL" = "sep" ]]
			then
				grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g" | sed -e "s/ /$SEP/g"
			else
				grep -v -w "$WORD" "$NEW" | sed -e "s/^/$WORD /g"
			fi
		fi
		if [[ "$BOUCLE" = "$MAX" ]]
		then
		return 0
		fi
	done < "$DICO" | head -n "$MAX" | tee -a "$TMP" | sed -e "s/ /$SEP/g"
}

############
## Compression ##
############

function PERMX()
{	
	TMP="${TIME}_PASSE_${PASSE}.7z"
	BOUCLE=""
	while read WORD
	do
		if [[ -n "$WORD" ]]
		then
			(( BOUCLE++ ))
			7z e  "$NEW" -so 2>/dev/null | grep -v -w "$WORD" | sed -e "s/^/$WORD /g"
		fi
		if [[ "$BOUCLE" = "$MAX" ]]
		then
		return 0
		fi
	done < "$DICO" | head -n "$MAX" | 7z a "$TMP" -si &>/dev/null
}

############
## Permutation ##
############

function PERMUTE()
{
	if [[ "$1" = "2" ]]
	then
		ARCH="${TIME}_PASSE_1.7z"
		7z a "$ARCH" "$NEW"  &>/dev/null
		rm "$NEW"
		NEW="$ARCH"
		(( SEQ-- ))
	fi
	while [[ ! "$NUM" = "$SEQ" ]]
	do
		PASSE="$(( NUM + 1 ))"
		if [[ "$PASSE" = "$SEQ" ]]
		then
			if [[ "$NULL" = "0" ]]
			then
				NULL="sep"
			fi
			if [[ ! "$COMPRESSE" = "0" ]]
			then
			MAX="$NBRM"
			fi
		fi
		case "$1" in
			0)
				PERMQUICK;;
			1)
				PERMTEE;;
			2)
				PERMX;;
		esac
		mv -f  "$TMP"  "$NEW"
		(( NUM++ ))
	done
	if [[ "$1" = "2" ]]
	then
		7z a  "$NEW" "$DICO" &>/dev/null
		echo "SEP=\"$SEP\"" > "${TIME}_DICO.sep"
		7z a  "$NEW"  "${TIME}_DICO.sep" &>/dev/null
		rm "${TIME}_DICO.sep" "$DICO"
		DICO="${TIME}_DICO.7z"
	fi
	mv -f "$NEW" "$DICO"
}

###########
## Nettoyage ##
###########

function CLEAN()
{
	rm "$DICO"
	if [[ -d "$WDIR" ]]
	then
		rmdir "$WDIR"
	fi
}

###########################################
## Convertion octets -> Kio -> Mio -> Gio -> Tio -> Pio -> Eio -> Zio -> Yio ##
###########################################

function CONVERTION()
{
	COUNT="1024"
	
	for i in K M G T P E Z Y
	do
	if COMPARE "$1" "$COUNT"
	then
		CONV="$(bc<<<"scale=2; $1/$COUNT")"
		echo "Soit $CONV $i"io 1>&2
		COUNT="$(bc<<<"$COUNT*1024")"
	else
		return 0
	fi
	done
}

################################################
## Résoudre le probleme des chaines longues dans les comparaisons nnumériques ##
################################################

function COMPARE()
{
	ZERO="$(bc<<<"$1<=$2")"
	return "$ZERO"
}

###################
## Lire une archive ULTRA ##
###################

function READ()
{
	ZIP="$1"
	NOM_ZIP="$(basename "$1")"
	DICT="$(echo "$NOM_ZIP" | cut -d'.' -f1)"
	TXT_DICT="$DICT.txt"
	TXT_SEP="$DICT.sep"
	eval $(7z e -so "$ZIP" -- "$TXT_SEP" 2>/dev/null | cat)

	while read WORD
	do
		if [[ es"$SEP"pace = "es pace" ]]
		then
			7z e -so "$ZIP" -- "$DICT" 2>/dev/null | grep -v -w "$WORD" | sed -e "s/^/$WORD /g"
		else
			7z e -so "$ZIP" -- "$DICT" 2>/dev/null | grep -v -w "$WORD" | sed -e "s/^/$WORD /g" | sed "s/ /$SEP/g"
		fi
	done <<<"$(7z e -so "$ZIP" -- "$TXT_DICT" 2>/dev/null | cat)"
}

################
## On parse les options ##
################

while getopts ":l:L:w:i:d:r:P:s:vyCh" OPT_PASS
do
	case "$OPT_PASS" in
	l)
		LONGMIN="$OPTARG";;
	L)
		LONGMAX="$OPTARG";;
	w)
		SEQ="$OPTARG";;
	i)
		ORIGINAL="$OPTARG"
		if [[ ! -e "$ORIGINAL" ]]
		then
			echo "Le fichier n'existe pas"
			exit 1
		fi
		DIR="${ORIGINAL%/*}";;
	v)
		VITESSE="1";;
	d)
		WDIR="$OPTARG"
		mkdir -p "$WDIR"
		DIR="$WDIR";;
	y)
		REPONSE="y";;
	C)
		COMPRESSE="0";;
	r)
		ZIP="$OPTARG"
		if [[ ! -e "$ZIP" ]]
		then
			echo "Le fichier n'existe pas"
			exit 1
		fi
		if [[ "$(file "$OPTARG" | grep -w "7-zip")" = "1" ]]
		then
			echo "Cette archive n'est pas pris en charge"
			exit 1
		fi
		READ "$ZIP"
		exit 0;;
	P)
		NBRM="$OPTARG";;
	s)
		SEP="$OPTARG"
		NULL="0";;
	h)
		HELP
		exit 0;;
	*)
		HELP
		exit 1;;
	esac
done

#################
## Pas d'options -> help ##
#################

if [[ "$(echo "$@"no)" = "no" ]]
then
	HELP
	exit 1
fi
################################
## Le mode compression désactive le mode verbeux ##
################################


if [[ "$COMPRESSE" = "0" ]]
then
	if  [[ "$VITESSE" = "1" ]]
	then
		echo -e "Le mode compression et le mode verbeux sont inccompatibles"
	exit 1
	fi
	VITESSE="2"
fi

##########################
## On se place dans le dossier de travail ##
##########################

cd "$DIR"

#####################################
## On trie le dictionnaire en fonction de la longeur des mots ##
#####################################

LONGX="$(bc<<<"$LONGMAX +1")"
sed   "/^.\{$LONGMIN\}/!d; /^.\{$LONGX\}/d" "$ORIGINAL" | sort -u | sort -R > "$DICO"

##################################
## On reccupere le nombre de mots du dictionnaire trié ##
##################################

LIGNE="$(wc -l "$DICO" | cut -d' ' -f1)"
MULTIPLI="$LIGNE"

#############################################################
## Si le nombre de mots par phrases à créer est supérieur au nombre de mot du dictionnaire , on quitte ##
#############################################################

if COMPARE   "$SEQ"  "$LIGNE"
then
	echo "Le nombre de mots composants la phrase doit être égal ou inférieur au nombre de mots composants le dictionnaire :
	Nombre de lignes du dictionnaire : $LIGNE
	Nombre de mots par phrase :$SEQ "
	rm "$DICO"
	exit 1
fi

###########################
## Calcul du poid et du nombre de phrases ##
###########################

POID="$(stat -c %s "$DICO")"
PMOY="$(bc<<<"$POID/$LIGNE")"
MAX="$(bc<<<"($NBRM/($LIGNE-$SEQ))+1")"

while [[ "$NBR" != "$SEQ" ]]
do
	(( NBR ++ ))
	MULTIPLI="$(bc<<<"$MULTIPLI - 1")"
	FACT="$(bc<<<"$FACT*$MULTIPLI")"
done

PHRASE="$(bc<<<"$LIGNE*$FACT")"
TOTAL="$(bc<<<"$POID*$FACT*$SEQ")"
PTOT="$(bc<<<"$PMOY*$SEQ*$NBRM")"

if COMPARE "$NBRM" "$PHRASE"
then
	PTOT="$TOTAL"
	NBRM="$PHRASE"
fi

if [[ "$VITESSE" = "2" ]]
then	
	TOTAL="$(bc<<<"($TOTAL+$POID)/(16*$MULTIPLI)")"
	PTOT="$(bc<<<"($PTOT+$POID)/(16*$MULTIPLI)")"
fi


##################################################
## On invite l'utilisateur à choisir si oui ou non il souhaite exploser son disque dur :) ##
##################################################

LIBRE="$(bc<<<"$(df "$DICO" | grep dev | awk '{ print $4 }')*1024")"
echo "Espace libre disponible : $LIBRE octets"
CONVERTION "$LIBRE"

echo -e "\n\
Nombre de lignes du dictionnaire : $LIGNE
Longueur minimal des mots : $LONGMIN
Longueur maximal des mots : $LONGMAX
Nombre de mots par phrase : $SEQ
Nombre de phrases à générées : $PHRASE
Poid du fichier généré : $TOTAL octets"
CONVERTION "$TOTAL"

echo -e "\n\
Nombre de phrases limitées à : $NBRM
Poid supposé du fichier généré : $PTOT octets"
CONVERTION "$PTOT"

if COMPARE "$PTOT" "$LIBRE"
then
	echo -e "\nVous ne disposez pas de l'espace disque nécessaire !\nVeuillez corriger les options sélectionnées ."
	exit 1
fi

##############
## On lance la bête ##
##############

if [[ "$REPONSE" = "n" ]]
then
	echo -e "\nSouhaitez vous poursuivre ?\n[y/n]" 1>&2
	read REPONSE
else
	echo -e "\nExécution sans confirmation" 1>&2
fi


case "$REPONSE" in
	y) 
		cp "$DICO" "$NEW"
		time PERMUTE "$VITESSE";;
	n)
		echo "On quitte"
		CLEAN
		exit 0;;
	*)
		echo "Choix invalide , on quitte ."
		CLEAN
		exit 1;;
esac

TOTAL="$(stat -c %s "$DICO")"

##############################
## Quelques informations sur le fichier produit ##
##############################

echo -e "\n\
Fichier de sortie : $DIR/$DICO
Poid du fichier produit : $TOTAL octets" 1>&2
CONVERTION "$TOTAL"
echo -e "\nSouhaitez vous vérifier le nombre de phrases générées ?\nAttention cette opération peut être très longue\n[y/n]" 1>&2
read VERIF
if [[ "$VERIF" = "y" ]]
then
	if [[ "$VITESSE" = "2" ]]
	then
		NBR_PH="$(READ "$DICO" | wc -l | cut -d' ' -f1)"
	else
	NBR_PH="$(wc -l "$DICO" | cut -d' ' -f1)"
	fi
	echo -e "\nNombre de phrases générées : $NBR_PH" 1>&2
fi

exit 0

Dernière modification par Yannou90 (Le 04/02/2013, à 00:44)

Hors ligne

#22 Le 03/02/2013, à 13:46

nicolas66

Re : Bash : permuter mots et creation de phrase à partir d'un dictionnaire

Yannou90 a écrit :

@nicolas66
Bon apres reflexion il est vrai que ce topic pourrait être deplacé , mais bon ...

Bah oui, le forum "Vos développements libres" serait tout de même plus adapté. Je laisse les modos décider ...


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne