2016-04-05 40 views
3

Kodlanmış bir dosya yazmaya çalışıyorum. Dosyada 9 ila 12 bit semboller var. Bir dosya yazarken, bu dosyanın kodunu çözemediğim için doğru şekilde yazılmadığını tahmin ediyorum. Dosyada sadece 8 bitlik semboller varsa. Her şey iyi çalışıyor. Bu benim aynı8 bitlik sembolleri okuyun ve yazın

File.AppendAllText(outputFileName, WriteBackContent, ASCIIEncoding.Default); 

ReadAllText işlev çağrısı ile okumaya giden bir dosyayı yazıyorum yoludur.
Buraya gitmenin yolu nedir?


Ben RS kodlayıcı kullanırken dosyamı kodlamak için ZXing kitaplığı kullanıyorum. kodda Ben 12 bitlik sembol demektir AZTEC_DATA_12 ile benim Encoder başlatılıyor am gibi

ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);//if i use AZTEC_DATA_8 it works fine beacuse symbol size is 8 bit 
int[] bytesAsInts = Array.ConvertAll(toBytes.ToArray(), c => (int)c); 
enc.encode(bytesAsInts, parity); 
byte[] bytes = bytesAsInts.Select(x => (byte)x).ToArray(); 
string contentWithParity = (ASCIIEncoding.Default.GetString(bytes.ToArray())); 
WriteBackContent += contentWithParity; 
File.AppendAllText(outputFileName, WriteBackContent, ASCIIEncoding.Default); 

. RS Encoder int dizisi gerektirdiğinden, int dizisine dönüştürüyorum. Ve burada gibi dosyaya yazma. Ama AZTEC_DATA_8 ile değil 8 bitlik sembolün AZTEC_DATA_8 beacue ile iyi çalışıyor.

cevap

3

Ana sorun buradadır: tek bayt tek tamsayılar dönüştürürken Temelde sonucun kısmını atıyor

byte[] bytes = bytesAsInts.Select(x => (byte)x).ToArray(); 

. Eğer encode() çağrısının dizinin bakarsak


, dizi öğelerinin bazılarını 255'ten bir değer daha yüksek olduğunu görebilirsiniz, böylece bayt olarak temsil edilemez. Bununla birlikte, yukarıdaki kodda, her bir öğeyi tamsayı dizisinde 255'ten büyük bir değere sahip olduğunda öğeyi değiştirerek bayt olarak atarsınız.

encode() sonucunu saklamak için, tamsayıyı dönüştürmeniz gerekir. Bir bayt dizisine, değerlerin kaybolmadığı veya değiştirilmeyeceği şekilde dizilir.

Bayt dizileri ile tamsayı dizileri arasında bu tür bir dönüştürme yapmak için Buffer.BlockCopy() işlevini kullanabilirsiniz. Bu işlevin nasıl kullanıldığına bir örnek in this answer'dur.

Örnekleri her iki dönüşüm için de yanıttan ve yorumdan yanıta kullanın: Bir bayt dizisini bir tamsayı dizisine kodlama() işlevine geçmek ve kodlamadan döndürülen tamsayı dizisini döndürmek için () bir bayt dizisine geri dönün.

İşte bağlantılı cevap örnek kodlar şunlardır:


// Convert byte array to integer array 
byte[] result = new byte[intArray.Length * sizeof(int)]; 
Buffer.BlockCopy(intArray, 0, result, 0, result.Length); 

// Convert integer array to byte array (with bugs fixed) 
int bytesCount = byteArray.Length; 
int intsCount = bytesCount/sizeof(int); 
if (bytesCount % sizeof(int) != 0) intsCount++; 
int[] result = new int[intsCount];    
Buffer.BlockCopy(byteArray, 0, result, 0, byteArray.Length); 
Şimdi dosyalarına veri depolama hakkında: Encoding.GetString() üzerinden doğrudan bir dize veri açmayın. Tüm bit dizileri, belirli bir karakter kümesindeki karakterlerin geçerli temsilidir. Bu nedenle, rastgele bir dizi rasgele diziyi bir dizeye dönüştürmek bazen başarısız olur.

Bunun yerine, ya da mağaza/File.WriteAllBytes()/File.ReadAllBytes() ile bir dosya doğrudan bayt dizisi okumak veya bayt dizisi base64 kodlanmış dizi gösterimi ile çalışmak Convert.ToBase64() ve Convert.FromBase64() kullanın.

ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);//if i use AZTEC_DATA_8 it works fine beacuse symbol size is 8 bit 
    int[] bytesAsInts = Array.ConvertAll(toBytes.ToArray(), c => (int)c); 
    enc.encode(bytesAsInts, parity); 

    // Turn int array to byte array without loosing value 
    byte[] bytes = new byte[bytesAsInts.Length * sizeof(int)]; 
    Buffer.BlockCopy(bytesAsInts, 0, bytes, 0, bytes.Length); 

    // Write to file 
    File.WriteAllBytes(outputFileName, bytes); 

    // Read from file 
    bytes = File.ReadAllBytes(outputFileName);    

    // Turn byte array to int array 
    int bytesCount = bytes.Length * 40; 
    int intsCount = bytesCount/sizeof(int); 
    if (bytesCount % sizeof(int) != 0) intsCount++; 
    int[] dataAsInts = new int[intsCount]; 
    Buffer.BlockCopy(bytes, 0, dataAsInts, 0, bytes.Length); 

    // Decoding 
    ReedSolomonDecoder dec = new ReedSolomonDecoder(GenericGF.AZTEC_DATA_12); 
    dec.decode(dataAsInts, parity); 
: Burada Kombine


bazı örnek kod