C'est un truc simple que j'avais développé pour commencer mon truc de lectures de cartes imprimées (transposage de bits sur une image pour récupération via un scanner, à la manière des antiques cartes perforées). Je devais trouver comment extraire les 8 bits d'un octet facilement, et je devais aussi pouvoir composer des octets à partir de bits. Chose qui était à l'époque difficile ... Je n'avais même pas de scanner, donc je devais aussi pouvoir entrer les bits moi-même et recomposer le fichier.
J'ai commenté cette source pour les débutants, il s'agit d'une source simple sans prétention.
Source / Exemple :
// Créé par David L.Pratte <Mykeys Admin>
using System;
using System.IO;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace PTS
{
/// <summary>
/// Classe de test de lecture/écriture de trucs binaires ;)
/// </summary>
public class BinController
{
/// <summary>
/// Lit les bits et retourne une chaîne de caractères.
/// Les bits sont regroupés en groupe de 8 pour une meilleure lisibilité
/// </summary>
/// <param name="fichier">Le fichier à lire</param>
/// <returns>Les bits en forme de chaîne de caractère</returns>
public static string BitsRead(FileInfo fichier){
//Si le fichier existe
if (fichier.Exists){
//Variable qui servira à insérer les bits
string bits = "";
//Ouverture du fichier en lecture (création d'un flux)
FileStream fluxFichier = fichier.OpenRead();
//Le lecteur binaire pour la lecture simple du flux
BinaryReader lecteurBinaire = new BinaryReader(fluxFichier);
//Tant qu'il reste des données dans le fichier
while(lecteurBinaire.PeekChar() != -1){
//On lit l'octet (8 bits)
byte b = lecteurBinaire.ReadByte();
/* On passe tous les bits dans l'octet. Un octet se constitue ainsi: 01100110 (tous les bits peuvent être 0 ou 1)
- Un bits peut prendre 2 valeurs, 0 et 1
- les puissances de 2 sont donc utilisés pour composer l'octet:
- 0 = 0 x 2^7 = 0
- +1 = 1 x 2^6 = 64
- +1 = 1 x 2^5 = 32
- +0 = 0 x 2^4 = 0
- +0 = 0 x 2^3 = 0
- +1 = 1 x 2^2 = 4
- +1 = 1 x 2^1 = 2
- +0 = 0 x 2^0 = 0
- Ce qui donne donc le nombre 102 exprimé en binaire
- Le bit le plus important se situe à l'extrême gauche, puisque c'est celui qui peut atteindre la plus grande valeur (2^7 , c'est à dire 128)
- ----
- L'opérateur << sert à décaler les bits
- 1 << 3, par exemple, donne ceci:
- 1 en binaire = 1
- décalage de 3 positions = 1000, c'est à dire 16 dans notre manière de compter
- en décalant 1 de i positions, on obtient donc 2^i
- ---
- L'opérateur & (x & y) sert à dire à l'ordinateur : Mets 1 dans les bits du résultat ou les bits sont à 1 dans x et dans y
- Exemple:
- 102 & 16
- 102 = 01100110
- 16 = 00001000
- REP = 00000000 (aucun bit n'est identique)
- Ce qui donnera 0
-
- Exemple 2:
- 102 & 63
- 102 = 01100110
- 63 = 00111111
- REP = 00100110
- Ce qui donnera 38
-
- En testant avec 2^i, les résultats possibles seront donc 0 (bit à 0) ou 2^i (bit à 1)
- L'exploitation de ces résultats permet de conserver les bits */
for (sbyte i=7;i>=0;i--){
bits += (((b & 1<<i) > 0)?1:0).ToString();
}
bits+=" ";
}
//on ferme le fichier
fluxFichier.Close();
return bits;
}
return "";
}
public static void BitsWrite(string bits,FileInfo fichier){
//Cette RegEx vérifie qu'il y a une chaîne de 0 et de 1 ([0-1]+) du début de la chaîne(^) à la fin($)
Regex rgx = new Regex("^[0-1]+$");
//On enlève les espaces
bits = bits.Replace(" ","");
//Si la chaîne est une suite de 0 et de 1 et qu'on a donné un nom de fichier
if (rgx.IsMatch(bits) && fichier.FullName != ""){
//On ouvre le fichier pour pouvoir écrire dedans
FileStream fluxFichier = fichier.OpenWrite();
//On crée un écriveur pour traiter facilement le flux
BinaryWriter ecriveurBinaire = new BinaryWriter(fluxFichier);
//Tant qu'il y a des groupes de 8 bits
for(int i = 0;i<bits.Length;i+=8){
//on crée une variable qui contiendra notre octet
byte buffer=0;
//on passe chaque bit de l'octet
for (byte n=0;n<=7;n++){
//on parse le bit qu'on veut dans la chaîne et on lui applique son importance (2^n) et on additionne ça dans l'octet
buffer += (byte)(byte.Parse(bits[i+n].ToString()) << (7-n));
}
//on écrit l'octet dans le fichier
ecriveurBinaire.Write(buffer);
}
//on ferme le fichier
fluxFichier.Close();
}
}
}
}
Conclusion :
J'ai jamais été bon pour décrire les trucs, donc, si vous avez une meilleure façon de décrire la structure d'un octet et les opérateurs & et <<, je suis preneur.
26 août 2009 à 20:03
1 nov. 2006 à 12:49
Je cherche la possibilité d'éditer des fichiers non-texte pour modifier des noms de clients à l'intérieur, sans changer le reste du fichier ...
Merci beaucoup
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.