代码之家  ›  专栏  ›  技术社区  ›  Andrew Ensley

帮助进行字节移位

  •  2
  • Andrew Ensley  · 技术社区  · 15 年前

    moz-byteshift.pl ( documentation ).这正是我想做的,但我需要用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#中的等效示例代码更好。=)

    谢谢你的帮助。

    3 回复  |  直到 15 年前
        1
  •  4
  •   Michael Carman    15 年前

    没什么好说的。它一次读取一个字节的文件,将每个字节的值调整为任意值(通过-s标志指定),然后写出调整后的字节。它是文本文件的ROT-13加密的二进制等价物。

    其余的细节是特定于Perl如何做这些事情的。getopts()是一个处理命令行开关的函数(来自Getopt::Std模块)。binmode()将文件句柄置于原始模式,以绕过Perl在I/O期间通常执行的任何魔术。sysread()和syswrite()函数用于低级流访问。pack()和unpack()函数用于读取和写入二进制数据;Perl不执行本机类型。

    在C中重新实现这一点很简单。我建议这样做(如果需要,从C绑定到它),而不是直接移植到C。

        2
  •  1
  •   samjudson    15 年前

    从其他答案来看,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();
    }
    
        3
  •  1
  •   Sinan Ünür    15 年前

    代码的作用是:从标准输入中逐个读取每个字节(在将其切换到原始模式后,这样就不会发生转换)。解包获取刚刚读取的字符的字节值,以便“0”读取变为0x30。选择拉丁1编码,以使转换一致(例如,参见 http://www.cs.tut.fi/~jkorpela/latin9.html ).

    然后,命令行中使用-s选项指定的值与512一起添加到此字节,以模拟模运算。这样,-s0,-s256等是等效的。我不知道为什么需要这样做,因为我会假设下面的包已经处理好了,但我认为他们一定有很好的理由把它放在那里。

    然后,将原始字节写入标准输入。

    下面是在包含字符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....
    
    推荐文章