Frage

Ich muss eine Textdatei Byte-Verschiebung. Ich weiß absolut nichts über Perl, aber ich fand genannt perfekt funktionierende Stück Code in Perl moz-byteshift.pl ( Dokumentation ). Dies ist genau das, was ich tun will, aber ich brauche es in C # zu tun.

Hier ist der Quellcode der Perl-Datei:

#!/usr/bin/perl

# To perform a byteshift of 7
#   To decode: moz-byteshift.pl -s -7 <infile >outfile
#   To encode: moz-byteshift.pl -s  7 <infile >outfile

# To perform a byteshift of 13
#   To decode: moz-byteshift.pl -s -13 <infile >outfile
#   To encode: moz-byteshift.pl -s  13 <infile >outfile

use encoding 'latin1';
use strict;
use Getopt::Std;

use vars qw/$opt_s/;

getopts("s:");
if(!defined $opt_s) {
  die "Missing shift\n";
}

my $buffer;
while(1) {
  binmode(STDIN, ":raw");
  my $n=sysread STDIN, $buffer, 1;
  if($n == 0) {
    last;
  }
  my $byte = unpack("c", $buffer);
  $byte += 512 + $opt_s;
  $buffer = pack("c", $byte);
  binmode(STDOUT, ":raw");
  syswrite STDOUT, $buffer, 1;
}

Wenn jemand zumindest könnte erklären, wie der Perl-Skript funktioniert, das wäre toll. Beispielcode des Äquivalents in C # wäre besser. =)

Danke für die Hilfe.

War es hilfreich?

Lösung

Was der Code tut, ist dies: jedes Byte von der Standardeingabe eins nach dem anderen lesen (nachdem es in Rohmodus Schalt so keine Übersetzung auftritt). Der auspacken wird der Byte-Wert des Zeichens nur so gelesen, dass eine ‚0‘ verwandelt sich in 0x30 lesen. Die latin1 Codierung wird so gewählt, dass diese Umwandlung in Einklang steht (siehe zB http: // www .cs.tut.fi / ~ jkorpela / latin9.html ).

Dann auf der Kommandozeile der Wert mit der Option sich angegeben wird zusammen mit 512 zu diesem Byte hinzugefügt, um eine Modulo-Operation zu simulieren. Auf diese Weise, es 0, es 256 usw. äquivalent ist. Ich bin nicht sicher, warum dies notwendig ist, weil ich das folgende Pack Pflege nahm von den, angenommen hätte, aber ich denke, dass sie guten Grund gehabt haben muss, es dort zu setzen.

Dann schreiben Sie den rohen Byte Standardeingabe aus.

Hier ist, was passiert, wenn Sie es auf eine Datei ausgeführt enthält die Zeichen 012345 (Ich habe die Daten in dem DATA ):

E:\Test> byteshift.pl -s 1 | xxd
0000000: 3132 3334 3536 0b                        123456.

Jedes Byte-Wert um eins erhöht.

E:\Test> byteshift.pl -s 257 | xxd
0000000: 3132 3334 3536 0b                        123456.

Denken Sie daran, 257% 256 = 1. Das heißt:

$byte += $opt_s;
$byte %= 256;

ist äquivalent zu dem Schritt in dem Code verwendet wird.

Sehr viel später: OK, ich weiß nicht, C #, aber hier ist das, was ich in der Lage war, zusammen mit Online-Dokumentation Stück. Jemand, der C # kennt sollte dieses Problem beheben:

using System;
using System.IO;

class BinaryRW {
    static void Main(string[] args) {
        BinaryWriter binWriter = new BinaryWriter(
                Console.OpenStandardOutput()
                );
        BinaryReader binReader = new BinaryReader(
                Console.OpenStandardInput()
                );

        int delta;

        if ( args.Length < 1 
                || ! int.TryParse( args[0], out delta ) )
        {
            Console.WriteLine(
                    "Provide a non-negative delta on the command line"
                    );
        } 
        else {       
            try  {
                while ( true ) {
                    int bin = binReader.ReadByte();
                    byte bout = (byte) ( ( bin + delta ) % 256 );
                    binWriter.Write( bout );
                }
            }

            catch(EndOfStreamException) { }

            catch(ObjectDisposedException) { }

            catch(IOException e) {
                Console.WriteLine( e );        
            }

            finally {
                binWriter.Close();
                binReader.Close();

            }
        }
    }
}

E:\Test> xxd bin
0000000: 3031 3233 3435 0d0a 0d0a                 012345....

E:\Test> b 0 < bin | xxd
0000000: 3031 3233 3435 0d0a 0d0a                 012345....

E:\Test> b 32 < bin | xxd
0000000: 5051 5253 5455 2d2a 2d2a                 PQRSTU-*-*

E:\Test> b 257 < bin | xxd
0000000: 3132 3334 3536 0e0b 0e0b                 123456....

Andere Tipps

Es gibt nicht viel zu sagen. Er liest eine Datei mit einem Byte zu einer Zeit, stellt den Wert jedes Bytes von einem beliebigen Wert (über das es Flag angegeben) und schreibt das geändertene Bytes aus. Es ist das binäre Äquivalent von ROT-13-Verschlüsselung einer Textdatei.

Der Rest der Details sind spezifisch, wie Perl, diese Dinge tut. getopts () eine Funktion (vom Getopt :: Std-Modul), die Befehlszeilenoptionen verarbeitet. binmode () setzt die Dateihandies im Raw-Modus eine der Magie zu umgehen, die Perl normalerweise der Fall ist während der I / O. Die sysread () und syswrite () -Funktionen verwendet werden für Low-Level-Stromzugriff. Die Packung () und entpacken () Funktionen werden verwendet, um binäre Daten zu lesen und schreiben; Perl macht keine native Typen.

Dies wäre trivial in C neu zu implementieren ich würde empfehlen, tun (und um es von C # verbindlich, wenn es sein muss), anstatt eine Portierung auf C # direkt.

von den anderen Antworten zu urteilen das äquivalent in C # in etwa so aussehen:

using(Stream sIn = new FileStream(inPath))
{
  using(Stream sOut = new FileStream(outPath))
  {
    int b = sIn.ReadByte();
    while(b >= 0)
    {
      b = (byte)b+1; // or some other value
      sOut.WriteByte((byte)b);
      b = sIn.ReadByte();
    }
    sOut.Close();
  }
  sIn.Close();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top