Bonjour,
J'ai un problème, je pense, d'arrondi lorsque je fais des traitements sur des uint et ulong.
Contexte :
Je suis en train de travailler sur une librairie perso d'encryption de fichiers.
N'ayant aucune notion de cryptographie, mais fort du diction "diviser pour mieux régner", j'ai mis au point une méthode (certainement pas la meilleure) pour transformer en "bruit" n'importe quel fichier, et être capable de le reconstruire grâce à un dictionnaire.
En fait, pour faire simple, c'est un Huffman inversé.
Donc j'ai une chaîne "toto va à la plage".
=> Je compte chaque occurrence de chaque byte.
=> Puis je génère un dictionnaire qui prend cette fois non plus 256 valeurs possibles, mais 2^32 valeurs, en disant "bon le byte qui contient 't' peut être remplacé par n'importe quelle valeur entre X et Y". Le choix de la valeur entre X et Y se faisant de façon aléatoire, ce qui rend pour ainsi dire infini le nombre de version identiques d'un même fichier.
Et c'est au moment de la génération de ce dictionnaire que je pense, j'ai des soucis.
Voici un fichier en entrée :
Une version du fichier crypté : (c'est joli tout plein)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4Toto le haricot Ceci est un test pour voir si ça marche Et franchement, j'aimerais bien que ça marche !
Et enfin, la version presque décryptée car j'ai un bug :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Cöná¼Þá§z¢¶w¡%!©ÞË*Þ sJ+ù5ýÁË*QR*ÇVñ(*7[z§¿4¢¶ï¬Ca 4£cá>û7ljJ+È[êx-uÀ%Zë xJ+UÚ|iÙâ§z\/edó(¬±iF/-V""â&H5}ìÜñßÈù¹âèôV!ïû¶Þ*òï@¦ÖÜï6®¨qùÎÁ[®§²Ðºº-®¨6Ú2? (*&eeþô ÎS³pﮧªdOıÇVèaS½ÚNôì}§{ÒóÈùOr×õfáNBV!ßè§zή¨¥aÑHÄï*&H]ô {¿g*nøÓ¤!cl>5(°&Gòéèû<ÞV"~í9Ù¹6XR$ìÜ`§EbÔmøÓLÌFQÄkª¡Ú4¢Å"dóZ~Íý±În¥*psf4dÒÆ7Oø½agøÓ51V""ÿí®Iöni®§Ý¦ò Iön³Ñì÷d©ß/Ú/wìÝV!Á8]OÔ
Ça marche presque pas mal... Mais comme à mon habitude, y'a jamais moyen d'avoir un programme qui marche à 100%...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Toto ÿe haricot ÿeci est un test pour vpir si ça marche Tt franchement, j!aimerais cien que ça marche !
Alors voici des parties de code susceptibles d'être responsables. Je n'arrive pas à comprendre où ça merde :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 dictionary = new byte[256 * 8]; byte[] arr1 = new byte[4]; byte[] arr2 = new byte[4]; for (int i = 0, cpt = this.Capacity; i < cpt; i++) { this[i].Position = (uint)(((ulong)uint.MaxValue * (ulong)this[i].Position) / (ulong)total); this[i].Length = (uint)(((ulong)uint.MaxValue * (ulong)this[i].Length) / (ulong)total); UInt32ToByte(arr1, 0, this[i].Position); UInt32ToByte(arr2, 0, this[i].Length); AddToDictionary(arr1, arr2, i * 8); } private void AddToDictionary(byte[] arr1, byte[] arr2, int index) { dictionary[index + 0] = arr1[0]; dictionary[index + 1] = arr1[1]; dictionary[index + 2] = arr1[2]; dictionary[index + 3] = arr1[3]; dictionary[index + 4] = arr2[0]; dictionary[index + 5] = arr2[1]; dictionary[index + 6] = arr2[2]; dictionary[index + 7] = arr2[3]; } private static void UInt32ToByte(byte[] arr, int index, ulong value) { arr[index + 0] = (byte)(value >> 24); arr[index + 1] = (byte)((value >> 16) & 0xFF); arr[index + 2] = (byte)((value >> 8) & 0xFF); arr[index + 3] = (byte)(value & 0xFF); } private static uint BytesToUInt32(byte[] arr, int index) { return ((uint)arr[index + 0] << 24) | (((uint)arr[index + 1] << 16) & 0xFF) | (((uint)arr[index + 2] << 8) & 0xFF) | ((uint)arr[index + 3] & 0xFF); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public void Encrypt(byte[] arr, byte value) { UInt32ToByte(arr, 0, UInt32Random(this[value].Position, this[value].Length, rnd)); } private static uint UInt32Random(uint min, uint length, Random rand) { byte[] buf = new byte[8]; rand.NextBytes(buf); ulong ulongRand = (ulong)BytesToUInt32(buf, 0); return (uint)(ulongRand % (ulong)length + (ulong)min); }Si une âme charitable pouvait jeter un oeil là dessus et me dire où j'ai pu faire une bêtise...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public byte Decrypt(byte[] arr) { uint value = BytesToUInt32(arr, 0); for (int i = 0; i < 256; i++) { if (this[i].Position <= value && this[i].Position + this[i].Length > value) { return (byte)i; } } return 255; }
En pièce jointe, vous trouverez les sources complètes (aucun commentaire, ni documentation pour le moment).
Partager