Remplir un tableau à partir d'un fichier texte [Résolu/Fermé]

Signaler
Messages postés
23
Date d'inscription
samedi 9 mai 2015
Statut
Membre
Dernière intervention
20 mai 2015
-
Messages postés
23
Date d'inscription
samedi 9 mai 2015
Statut
Membre
Dernière intervention
20 mai 2015
-
Salutation
Je suis en Terminale et pour notre projet de BAC d'ISN nous devons crypter un message grâce aux décimales de pi, nous avons presque fini notre programme mais nous n'arrivons pas à :
ouvrir le ficher texte dans lequel se trouve les décimales de pi (en binaire) et les stocker dans un tableau.
J'ai déjà essayé d'utiliser la fonction Bufferedreader mais je n'arrive pas à la faire fonctionner.
Merci d'avance guypaul2

2 réponses

Messages postés
592
Date d'inscription
vendredi 7 août 2009
Statut
Membre
Dernière intervention
3 juin 2017
102
Salut, tu peux détailler un peu plus ton soucis ?
Messages postés
592
Date d'inscription
vendredi 7 août 2009
Statut
Membre
Dernière intervention
3 juin 2017
102
C'est faux cela existe en java, il suffit de changer ton ArrayList en Long au lieu de Integer et pour la conversion String to Long il faut utiliser la fonction Long.parseLong(String s)
Messages postés
16308
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 avril 2021
2 823 >
Messages postés
592
Date d'inscription
vendredi 7 août 2009
Statut
Membre
Dernière intervention
3 juin 2017

"C'est faux cela existe en java, il suffit de changer ton ArrayList en Long au lieu de Integer"
Dans ce cas on parle du type long, pas du type long long int comme il y a en C.

Mais un long c'est insuffisant car cela fait 64 bits alors qu'il en faut 3000 ici...
Le BigInteger parait donc plus adapté (puisqu'il peut gérer des millions de bits).
Messages postés
23
Date d'inscription
samedi 9 mai 2015
Statut
Membre
Dernière intervention
20 mai 2015

import java.math.BigInteger;
import java.io.*;
import java.util.ArrayList;
void main () {

  String fichier ="C:\\monfichier.txt";
  ArrayList<Integer> decimale = new ArrayList<Integer>();
  
  //lecture du fichier texte 
  try{
   InputStream ips=new FileInputStream(fichier); 
   InputStreamReader ipsr=new InputStreamReader(ips);
   BufferedReader br=new BufferedReader(ipsr);
   String ligne;
   while ((ligne=br.readLine())!=null){
   int piBinaire = Integer.parseInt(ligne);
   decimale.add(piBinaire);
   }
   br.close(); 
  }  
  catch (Exception e){
  
  }
  Integer tab[] = new Integer[decimale.size()];
 tab = decimale.toArray(tab);
  for (int elem : tab){
       System.out.println (elem);}


il faut donc que je remplace le string fichier du début par la fonction biginteger?
Messages postés
16308
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 avril 2021
2 823
"il faut donc que je remplace le string fichier du début par la fonction biginteger?"
Non, pour moi le BigInteger est un moyen de faire les calculs avec tous les 0 et 1 de ton fichier et donc de faire tes xor avec les décimales de pi.

Exemple :

import java.io.File;
import java.math.BigInteger;
import java.util.Scanner;

void main() throws Exception {
	
   // Récupération des 0 et 1 du fichier
   String fileName = "C:/Users/wellenreiter/Documents/travail/.travail ts/ISN/pi/binairepi.txt";
   StringBuilder fileContent = new StringBuilder();
   Scanner sc = new Scanner(new File(fileName));
   while (sc.hasNextLine())
      fileContent.append(sc.nextLine());
   sc.close();
   
   // Manipulation des décimales de PI 
   BigInteger pi = new BigInteger(fileContent.toString(), 2);
   
   String message = "Hello World";
   println("Message à coder : " + message);
   BigInteger datas = new BigInteger(message.getBytes());

   BigInteger convert = datas.xor(pi);
   println("Message codé : " + convert.toString(36));

   BigInteger revert = convert.xor(pi);
   println("Message décodé : " + new String(revert.toByteArray()));
}
Messages postés
23
Date d'inscription
samedi 9 mai 2015
Statut
Membre
Dernière intervention
20 mai 2015
>
Messages postés
16308
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 avril 2021

j'apprécie vraiment l'aide mais nous avons déja fait une bonne partie du programme bien que ça ne soit pas fait d'une manière aussi "propre" de plus je suis incapable de faire un programme comme celui ci.Je voudrais juste savoir comment avoir un tableau de int avec les binaires de mon fichier
Messages postés
16308
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 avril 2021
2 823
"Je voudrais juste savoir comment avoir un tableau de int avec les binaires de mon fichier"

Ok, mais comment est organisé ton fichier ?

Est-ce que tu as un chiffre décimal (entre 0 et 9) écrit en binaire par ligne ou est-ce que c'est plusieurs chiffres qui se suivent ? Si tu as plus de 31 bits par ligne les int ne peuvent pas représenter ces valeurs (pas plus que les long si tu as plus de 63 bits par ligne), d'où les NumberFormatException...

Et que veux tu dans ton tableau ?

La valeur de chaque ligne dans une case ? Ou est-ce que dans une ligne du fichier il faut extraire plusieurs cases pour le tableau ? (voire, cumuler plusieurs lignes du fichier pour obtenir une seule case)

Un exemple serait le bienvenu : imaginons qu'au lieu d'avoir 3000 bits dans ton fichier tu n'en est que 100 (par exemple), quelles seraient les premières lignes de ton fichier et la valeur du tableau correspondant que tu voudrais ?
Messages postés
16308
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 avril 2021
2 823
Dans ce cas pour être sûr d'être bon, vous devriez considérer qu'un char a toujours 16 bits, ça évite d'avoir parfois 8, parfois 16 bits à gérer. Vous mettez donc tous vos bits dans votre premier tableau (la conversion avec Integer.toBinaryString se fait bien, il faut juste penser à rajouter les 0 devant s'il en manque).
Par contre au niveau de la lecture du fichier ça se simplifie, tu peux lire chiffre par chiffre et remplir directement ton tableau puisque tu sa taille est connue d'avance (puisqu'elle s'aligne sur la taille du message initial).

import java.io.File;
import java.util.Scanner;

void afficher(String message, int[] array, int szBlock) {
	print(message + "\t");
	for (int i = 0; i < array.length; i++) {
		if (i % szBlock == 0)
			print(" ");
		print(array[i]);
	}
	println();
}

void main() throws Exception {

	String zeros8 = "";
	for (int i = 0; i < 8; i++)
		zeros8 += "0";

	String zeros16 = "";
	for (int i = 0; i < 16; i++)
		zeros16 += "0";

	String mot = readString("Entrez votre message");

	int k = mot.length();

	int[] messagebinaire = new int[16 * k];

	for (int i = 0; i < k; i++) {
		String binary = Integer.toBinaryString(mot.charAt(i));
		binary = zeros16.substring(binary.length()) + binary;
		for (int j = 0; j < 16; j++)
			messagebinaire[16 * i + j] = binary.charAt(j) == '0' ? 0 : 1;
	}

	afficher("Message à crypter : ", messagebinaire, 16);

	int[] tab = new int[16 * k];

	Scanner sc = new Scanner(new File("C:/pi.txt"));

	for (int i = 0; i < 2 * k; i++) {
		String binary = sc.nextBigInteger(2).toString(2);
		binary = zeros8.substring(binary.length()) + binary;
		for (int j = 0; j < 8; j++)
			tab[8 * i + j] = binary.charAt(j) == '0' ? 0 : 1;
	}

	sc.close();

	afficher("Valeur de pi :\t", tab, 16);

	int[] messagecrypte = new int[16 * k];

	for (int i = 0; i < 16 * k; i++)
		messagecrypte[i] = messagebinaire[i] ^ tab[i];

	afficher("Message crypté : ", messagecrypte, 16);
}
Messages postés
23
Date d'inscription
samedi 9 mai 2015
Statut
Membre
Dernière intervention
20 mai 2015

Merci pour ce programme il ne nous reste plus qu'à décoder le message mais je pense que nous y arriverons tout seul.J'ai cependant quelques questions concernant ton programme.
Je ne comprend pas bien cette ligne :messagebinaire[16 * i + j] = binary.charAt(j) == '0' ? 0 : 1;
tout comme le bloc void afficher. Pourrais tu m'en dire plus sur leurs fonctionnement s'il te plait.
Messages postés
23
Date d'inscription
samedi 9 mai 2015
Statut
Membre
Dernière intervention
20 mai 2015

Il y a aussi les string zero8 et zero16 et cela que je ne comprend pas :binary = zeros16.substring(binary.length()) + binary;
Messages postés
16308
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 avril 2021
2 823
Alors :

1)
messagebinaire[16 * i + j] = binary.charAt(j) == '0' ? 0 : 1; 


C'est un raccourci d'écriture. On utilise l'opérateur ternaire :
variable = condition ? valeurSiVrai : valeurSiFaux

C' est équivalent à la structure
if (condition)
    variable = valeurSiVrai;
else
    variable = valeurSiFaux;

Dans le contexte, je veux regarder si le charAt(i) est '0' dans ce cas je donne la valeur 0 à la case du tableau, sinon (je sais que le caractère est '1) je donne la valeur 1 à la case du tableau.

On pourrait donc aussi faire :

if (binary.charAt(j) == '0')
    messagebinaire[16 * i + j] =  0;
else
    messagebinaire[16 * i + j] =  1;

Ça revient au même, mais le code est plus long, et il y a deux fois le même code, pour identifier la case messagebinaire[16 * i + j], c'est dommage.

2) La méthode
void afficher(String message, int[] array, int szBlock)
c'est une manière de factoriser le code, je vais faire trois affichages pour les tableaux messagebinaire, tab et messagecrypte, c'est pénible d'écrire trois fois le même code pour faire la même chose. Alors j'ai fait cette petite méthode d'affichage pour éviter cette redondance de code. En soit, la méthode ne fait pas grand chose si ce n'est afficher un message ainsi que chaque case du tableau, séparés par des espaces pour aérer l'affichage.
De manière général, dès que tu commences à avoir deux codes qui font exactement la même chose, il faut penser à faire des méthodes pour regrouper le code, cela donne un code plus compréhensible.

3) les méthodes
Integer.toBinaryString(int)
et
BigInteger.toString(int)
ont le même inconvénient, elles représentent la valeur entière en binaire, mais en commençant par le premier chiffre significatif (un 1), or dans ton cas, tu as besoin des 0 qu'il y a avant.
Exemple : si tu as un décimal 12, ces méthodes vont renvoyer "1100" or ce que tu veux c'est l'affichage sur 8 bits ("00001100") pour les fractions de pi, voire sur 16 bits ("0000000000001100") pour représenter les caractères Unicode.
Pour rajouter les "000000..." qui manquent je fais une petite astuce, j'ai des variables zeros8 et zeros16 qui contiennent respectivement 8 et 16 "0", et si la représentation en binaire me donne "1100" avec 4 bits, je rajoute devant les 4 ou 12 "0" qui me manquent en faisant un substring.

Si je découpe, j'ai :
binary = "1100" // 4 bits
binary.length() = 4
zeros16="0000000000000000" // 16 zéros
zeros16.substring(binary.length())="000000000000" // 12 zéros
zeros16.substring(binary.length()) + binary = "0000000000001100" // 16 bits

Cela donne ce que l'on veux : le nombre binaire "1100" écrit sur 16 bits.
Messages postés
23
Date d'inscription
samedi 9 mai 2015
Statut
Membre
Dernière intervention
20 mai 2015

Nous avons rendu notre programme ce matin en état de marche ^^
(nous avons demandé à notre professeur si le faire sur 16 bits était mieux et il nous à dit que en effet cela permettait d'éviter certains problème comme tu me l'a dit, mais qu'ils se limiterons à exécuter le programme pour des caractères d'un octet on a donc changer le programme pour qu'il marche avec un octet par caractère).
Merci à vous pour cette grande aide que vous nous avez apporté et qui nous à été indispensable.