문제

텍스트 파일을 바이트 선택해야합니다. 나는 Perl에 대해 전혀 알지 못하지만 Perl에서 완벽하게 작동하는 코드를 발견했습니다. Moz-Byteshift.pl (선적 서류 비치). 이것은 내가하고 싶은 일을 정확하게하지만 C#에서해야합니다.

Perl 파일의 소스 코드는 다음과 같습니다.

#!/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;
}

누군가가 적어도 Perl 스크립트의 작동 방식을 설명 할 수 있다면 좋을 것입니다. C#의 동등한 샘플 코드가 더 나을 것입니다. =))

도와 주셔서 감사합니다.

도움이 되었습니까?

해결책

코드가하는 일은 다음과 같습니다. 표준 입력에서 각 바이트를 하나씩 읽으십시오 (원시 모드로 전환 한 후 변환이 발생하지 않음). 포장 풀기는 캐릭터의 바이트 값을 얻습니다. '0'읽기가 0x30으로 바뀝니다. Latin1 인코딩은이 변환이 일관되도록 선택됩니다 (예 : http://www.cs.tut.fi/~jkorpela/latin9.html).

그런 다음 -S 옵션이있는 명령 줄에 지정된 값이 512와 함께이 바이트에 추가되어 모듈러스 작동을 시뮬레이션합니다. 이런 식으로 -s 0, -s 256 등은 동일합니다. 나는 다음 팩이 그것을 처리했다고 가정했을 것이기 때문에 이것이 왜 필요한지 잘 모르겠지만, 그들은 그것을 거기에 넣을 충분한 이유가 있어야한다고 생각합니다.

그런 다음 원시 바이트를 표준 입력에 씁니다.

다음은 문자 012345가 포함 된 파일로 실행할 때 발생하는 일입니다 (데이터를 데이터 부분):

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

각 바이트 값은 하나씩 증가합니다.

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

257 % 256 = 1을 기억하십시오.

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

코드에 사용 된 단일 단계와 동일합니다.

훨씬 나중에 : 좋아, 나는 C#을 모른다. 그러나 여기 온라인 문서를 사용하여 함께 할 수 있었던 것이있다. C#을 아는 사람은 이것을 해결해야합니다.

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....

다른 팁

할 말이 많지 않습니다. 파일을 한 번에 하나씩 읽고 각 바이트의 값을 임의의 값 (-s 플래그를 통해 지정 됨)으로 조정하고 조정 된 바이트를 기록합니다. 텍스트 파일의 Rot-13 암호화와 동등한 이진입니다.

나머지 세부 사항은 Perl이 그러한 일을하는 방식에 따라 다릅니다. getOpts ()는 명령 줄 스위치를 처리하는 함수 (getOpt :: std module)입니다. BinMode ()는 파일 핸들을 원시 모드로 넣기 위해 I/O 동안 Perl이 일반적으로하는 마법을 우회합니다. sysread () 및 syswrite () 함수는 저수준 스트림 액세스에 사용됩니다. Pack () 및 Unpack () 함수는 이진 데이터를 읽고 쓰는 데 사용됩니다. Perl은 기본 유형을 수행하지 않습니다.

이것은 C에서 재 구현하기 위해 사소 할 것입니다. C#로 직접 포팅하기보다는이를 수행하고 필요한 경우 C#에서 바인딩하는 것이 좋습니다.

다른 답변에 의한 판단은 C#의 동등한 것이 다음과 같이 보일 것입니다.

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();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top