2010-08-08 4 views

Répondre

29

Dans le cas où vous n'avez pas ce fétiche LINQ, si commun ces derniers temps, vous pouvez essayer la voie normale

string input .... 
int numOfBytes = input.Length/8; 
byte[] bytes = new byte[numOfBytes]; 
for(int i = 0; i < numOfBytes; ++i) 
{ 
    bytes[i] = Convert.ToByte(input.Substring(8 * i, 8), 2); 
} 
File.WriteAllBytes(fileName, bytes); 

LINQ est grande, mais il Il doit y avoir des limites.

+0

Beaucoup plus compréhensible – jwsample

+1

Cela suppose que la longueur de la chaîne est un multiple de 8 ... Mais vous avez raison, c'est probablement plus facile à comprendre de cette façon. Je suppose que je suis totalement accro à LINQ;) –

+2

Hmm. Je dirais que le LINQ est plus compréhensible. Il décrit de manière concise ce qui est fait sans décrire les étapes (bruyantes) pour atteindre cet objectif. Il a un rapport contenu/bruit beaucoup plus élevé. – spender

9

Vous pouvez commencer par diviser la chaîne en une séquence de chaînes de 8 caractères, puis convertir ces chaînes en octets, et éventuellement écrire les octets dans un fichier

string input = "01110100011001010111001101110100"; 
var bytesAsStrings = 
    input.Select((c, i) => new { Char = c, Index = i }) 
     .GroupBy(x => x.Index/8) 
     .Select(g => new string(g.Select(x => x.Char).ToArray())); 
byte[] bytes = bytesAsStrings.Select(s => Convert.ToByte(s, 2)).ToArray(); 
File.WriteAllBytes(fileName, bytes); 

EDIT: Voici une autre façon de diviser la chaîne en morceaux de 8 caractères, peut-être un peu plus simple:

int nBytes = (int)Math.Ceiling(input.Length/8m); 
var bytesAsStrings = 
    Enumerable.Range(0, nBytes) 
       .Select(i => input.Substring(8 * i, Math.Min(8, input.Length - 8 * i))); 

Si vous savez que la longueur de la chaîne est un multiple de 8, vous pouvez le rendre encore plus simple:

int nBytes = input.Length/8; 
var bytesAsStrings = 
    Enumerable.Range(0, nBytes) 
       .Select(i => input.Substring(8 * i, 8)); 
+0

Vous venez de tomber dans cette question. Un beau problème de jouet ... bon pour une interview. Je pensais que j'essaierais avant de lire les réponses. Correspond à votre deuxième approche pratiquement terme pour terme. Moi aussi je suis accro à LINQ! +1 – spender

0

Les autres réponses vous ont couvert, mais juste pour le plaisir j'ai écrit le contraire. Allant de la chaîne à la ascii représentation binaire:

private static string StringToAsciiBin(string s) 
    { 
     string output = ""; 
     foreach (char c in s.ToCharArray()) 
     { 
      for (int i = 128; i >= 1; i /=2) 
      { 
       if (((int)c & i) > 0) 
       { 
        output += "1"; 
       } 
       else 
       { 
        output += "0"; 
       } 
      } 
     } 
     return output; 
    } 
+2

Vous voudriez passer d'un tableau d'octets à la représentation binaire. Un char est un type de données 16 bits, donc vous couper les huit premiers bits de chaque code de caractère. De même, n'utilisez pas + = pour construire une chaîne, elle est terriblement mauvaise, utilisez un StringBuilder à la place. – Guffa

3

Un peu en retard, mais voici mes 2 cents:

var binaryStr = "01110100011001010111001101110100"; 

var byteArray = Enumerable.Range(0, int.MaxValue/8) 
          .Select(i => i*8) 
          .TakeWhile(i => i < binaryStr.Length) 
          .Select(i => binaryStr.Substring(i, 8)) 
          .Select(s => Convert.ToByte(s, 2)) 
          .ToArray(); 
File.WriteAllBytes("C:\temp\test.txt", byteArray); 
0

En fait, la réponse par @Maciej est inexact. Comme @ Phate01 a remarqué le numOfBytes est correct seulement pour la longueur d'entrée qui est une puissance de 8. La deuxième chose est que le tableau d'octets devrait être rempli de n à 0 index pas l'inverse. Voici l'exemple de code:

var bits = "000011110000001000"; 
var numOfBytes = (int)Math.Ceiling(bits.Length/8m); 
var bytes = new byte[numOfBytes]; 
var chunkSize = 8; 

for (int i = 1; i <= numOfBytes; i++) 
{ 
    var startIndex = bits.Length - 8 * i; 
    if (startIndex < 0) 
    { 
     chunkSize = 8 + startIndex; 
     startIndex = 0; 
    } 
    bytes[numOfBytes - i] = Convert.ToByte(bits.Substring(startIndex, chunkSize), 2); 
} 

Cela peut être amélioré pour se débarrasser de la if statetment mais sous cette forme, il est plus compréhensible.

Questions connexes