我需要字节移位的文本文件。我知道绝对没有关于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;

是等效于在代码中使用的单个步骤。

很久以后:OK,我不知道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 ::标准模块),其处理命令行开关。 binmode()放文件句柄在原始模式绕过任何的是Perl中I / O照常魔法。所述sysread执行()和SYSWRITE()函数用于低级别的流的访问。的pack()的和解压()函数是用来读取和写入的二进制数据; 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