简体   繁体   English

命令行参数和“字节”数组

[英]Command Line arguments & "byte" arrays

So I have a generated byte array in the form of '\\xef\\x00\\xef\\x00' blah blah blah.所以我有一个以 '\\xef\\x00\\xef\\x00' 等等形式生成的字节数组。 The program is supposed to take this as an argument, encrypt it, and display the results.该程序应该将其作为参数,对其进行加密并显示结果。 The problem is that from command line it is '\\xef\\x00\\xef\\x00' so it doesn't work.问题是从命令行它是 '\\xef\\x00\\xef\\x00' 所以它不起作用。

I have tried various encodings (UTF8, Unicode, Default, etc).我尝试了各种编码(UTF8、Unicode、默认等)。 I have tried different "input" methods, but those are not desirable due to the source of the byte array's in the first place.我尝试了不同的“输入”方法,但由于首先是字节数组的来源,因此这些方法是不可取的。 The different input methods are like 0x00 format for the bytes instead.不同的输入方法类似于字节的 0x00 格式。

I have been googling for hours, but come up with nothing.我已经用谷歌搜索了几个小时,但一无所获。 Most things involving a byte array is "how to pass it to a method" >_<;大多数涉及字节数组的事情是“如何将其传递给方法”>_<;

static void Main(string[] args)
{
    //string one produces the desired results
    string one = "\xfc\xe8\x82\x00\x00";
    //args[0] is the same thing as string one..just command line
    //it IS never the same as strong one once "loaded"
    byte[] bytes = Encoding.GetEncoding(1252).GetBytes(args[0]);
    //various messing around trying to figure it out....
    string two = Encoding.UTF8.GetString(bytes);
    byte[] oneb = StrToByteArray(one);
    byte[] twob = StrToByteArray(two);
    Console.ReadKey();
}

public static byte[] StrToByteArray(string str)
{
    if (str != string.Empty)
    {
        byte[] sc = new byte[str.Length];

        for (int i = 0; i < str.Length; i++)
        {
            sc[i] = Convert.ToByte(str[i]);
        }

        return sc;
    }
    return null;
}

At the end...oneb and twob should be the same size, containing the same stuff.最后……oneb 和 twob 应该大小相同,包含相同的内容。

As the parameter is passed in, the string is being escaped, which is why you don't get it as a literal string.传入参数时,字符串被转义,这就是为什么您不将其作为文字字符串获取的原因。

You can use Regex.Unescape to turn the escaped string back into an un-escapaed one, then convert to an array if you need.您可以使用Regex.Unescape将转义的字符串转回未转义的字符串,然后根据需要转换为数组。

static void Main(string[] args)
{
    {
        string str = System.Text.RegularExpressions.Regex.Unescape(args[0]);

        var bytes = str.Select(c => (byte)c).ToArray();

        Console.WriteLine(str);
        Console.WriteLine(BitConverter.ToString(bytes));

        Console.ReadKey();
    }
}

Results:-结果:-

C:\Temp>ConsoleApp.exe \xfc\xe8\x82\x00\x00
üè?
FC-E8-82-00-00

I did find a temporary work around, but it isn't exactly what I would consider the "best" solution.我确实找到了一个临时解决方法,但这并不是我认为的“最佳”解决方案。 Anything that would work better I'm all ears.任何能更好地工作的东西我都听得一清二楚。

        public static byte[] StringToBytes2(string str)
        {
            string[] parts = str.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
            byte[] bytes = new byte[parts.Length];

            for (int i = 0; i < parts.Length; i++)
            {
                if (parts[i] != "")
                {
                    string temp = String.Format("0{0}", parts[i]);
                    bytes[i] = Convert.ToByte(temp, 16);
                }
            }
            return bytes;
        }

First, there's probably no convenient encoding scheme that will give you the raw bytes you're expecting.首先,可能没有方便的编码方案可以为您提供您期望的原始字节。 You can get the correct values out by converting each character in the string to a byte using LINQ:您可以通过使用 LINQ 将字符串中的每个字符转换为一个字节来获取正确的值:

string one = "\xfc\xe8\x82\x00\x00";
string oneBytes = one.Select(c => (byte)c).ToArray();

This works because the string constant in your program is transformed during compilation to be a string 5 characters long with the hex values as code points.这是有效的,因为程序中的字符串常量在编译期间被转换为 5 个字符长的字符串,以十六进制值作为代码点。

Now let's assume that you run your program and provide the same quoted string as an argument:现在让我们假设您运行程序并提供相同的带引号的字符串作为参数:

YourProgram.exe "\xfc\xe8\x82\x00\x00"

Now if you examine arg[0] in your program you'll find that it is 20 characters long instead of 5, and in the inspector it looks something like this:现在,如果您检查程序中的arg[0] ,您会发现它的长度为 20 个字符而不是 5 个,并且在检查器中它看起来像这样:

"\\xfc\\xe8\\x82\\x00\\x00"

That's because the argument is the literal text that was passed in, excluding the quotes, and escape characters are not interpreted.这是因为参数是传入的文字文本,不包括引号,并且不解释转义字符。

Aleks beat me to the punch on this one, but his solution is correct.亚历克斯在这一点上击败了我,但他的解决方案是正确的。 The Regex class has a method that takes an escaped string and interprets the escapes, which will give you the 5-character string you were looking for: Regex类有一个接受转义字符串并解释转义的方法,它将为您提供您正在寻找的 5 个字符的字符串:

var two = System.Text.RegularExpressions.Regex.Unescape(args[0]);
var twoBytes = two.Select(c => (byte)c).ToArray();

Now you'll have the same bytes in the two arrays.现在,您将在两个数组中拥有相同的字节。


Incidentally, don't try to use arbitrary bytes as string values and presume that they will be correctly reproduced in any particular encoding.顺便说一句,不要尝试使用任意字节作为字符串值,并假定它们会以任何特定编码正确再现。 In .Net strings are stored as Unicode, and so far I haven't found any encoding that won't result in changes in the first 256 code points ( \ - \ÿ ) during conversion.在 .Net 中,字符串存储为 Unicode,到目前为止,我还没有发现任何编码不会在转换过程中导致前 256 个代码点( \ - \ÿ )发生变化。 That's why the direct conversion from char to byte is your most direct option.这就是为什么从charbyte的直接转换是您最直接的选择。

Second, I hope you're only doing this for arguments.其次,我希望你这样做只是为了争论。 Using a string as a byte store is horribly wasteful.使用字符串作为字节存储是非常浪费的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM