Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Передать массив байт в консольную апликацию.  [new]
jenya7
Member

Откуда:
Сообщений: 1349
Я передаю аргументы
static void Main(string[] args)
{
    if (args[0] == "ааа")
    {

    }     
    
    if (args[1] == "bbb")
    {

    }    
}

а как мне красиво передать массив байт (byte[] data) одним аргументом?

Сообщение было отредактировано: 5 апр 21, 09:53
5 апр 21, 10:01    [22304216]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22306
закодируй в base64
5 апр 21, 10:05    [22304218]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22306
Только надо понимать, что размер аргумента не бесконечный
5 апр 21, 10:05    [22304219]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
jenya7
Member

Откуда:
Сообщений: 1349
Shocker.Pro
закодируй в base64

это как? а если размер массива 1024 байт?
5 апр 21, 10:10    [22304223]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
dvim
Member

Откуда: Санкт Петербург
Сообщений: 697
jenya7,

Ограничение консоли 8191 символов.
base64 увеличивает длину примерно раза в 2. ( Convert.ToBase64String и обратно)

Если размер больше - то надо смотреть на другие способы передачи данных ( файлы, реестр)
5 апр 21, 10:14    [22304228]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
jenya7
Member

Откуда:
Сообщений: 1349
dvim
jenya7,

Ограничение консоли 8191 символов.
base64 увеличивает длину примерно раза в 2. ( Convert.ToBase64String и обратно)

Если размер больше - то надо смотреть на другие способы передачи данных ( файлы, реестр)


то есть так?
bytes[] data = new bytes[1024];
Convert.ToBase64String(data );

а какая обратная операция? перевернуть стринг в массив байт?

string str =  Convert.ToBase64String(data );
bytes[] data = Convert.FromBase64String(str );


вроде так. ну если это работает то очень круто.

Сообщение было отредактировано: 5 апр 21, 10:29
5 апр 21, 10:34    [22304237]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22306
FromBase64String
5 апр 21, 10:35    [22304240]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4159
Как вариант, WinApi
https://github.com/BlueSkeye/Torefactor/blob/54cf965b084d83e1acc89c649b90ad443540d292/TorNet/Interop/Crypt32.cs
Формат строки будет типа 100FF245 и т.д.
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace ConsoleApp19
{
    class Program
    {
        internal static class CryptoApi
        {
            [DllImport("Crypt32.DLL")]
            internal static extern bool CryptBinaryToString(
                [In] byte[] pbBinary,
                [In] int cbBinary,
                [In] CrypBinaryFlags dwFlags,
                [In] byte[] pszString,
                [In, Out] ref int pcchString);

            [DllImport("Crypt32.DLL", CharSet = CharSet.Unicode)]
            internal static extern bool CryptStringToBinary(
                [In] string pszString,
                [In] int cchString,
                [In] CrypBinaryFlags dwFlags,
                [In] IntPtr pbBinary,
                [In, Out] ref int pcbBinary,
                [Out] out int pdwSkip,
                [Out] out int pdwFlags);

            [Flags]
            internal enum CrypBinaryFlags : uint
            {
                Base64WithHeader = 0x00000000,
                Base64 = 0x00000001,
                Binary = 0x00000002,
                Base64WithRequestHeader = 0x00000003,
                Hexadecimal = 0x00000004,
                HexadecimalWithAscii = 0x00000005,
                AnyBase64 = 0x00000006,
                AnyString = 0x00000007,
                AnyHexadecimal = 0x00000008,
                Base64WithX509CRLHeader = 0x00000009,
                HexadecimalWithAddress = 0x0000000a,
                HexadecimalWithAsciiAndAddress = 0x0000000b,
                RawHexadecimal = 0x0000000c,
                Strict = 0x20000000,
                NoCRLF = 0x40000000,
                NoCR = 0x80000000,
            }

            internal static byte[] Decode(string input, CrypBinaryFlags flags, int inputSize)
            {
                int outputSize = 0;
                int pdwSkip;
                int pdwFlags;
                if (!CryptStringToBinary(input, inputSize, flags, IntPtr.Zero,
                    ref outputSize, out pdwSkip, out pdwFlags))
                {
                    throw new Exception();
                }
                IntPtr nativeBuffer = IntPtr.Zero;
                try
                {
                    nativeBuffer = Marshal.AllocCoTaskMem(outputSize);
                    if (!CryptStringToBinary(input, inputSize, flags, nativeBuffer,
                        ref outputSize, out pdwSkip, out pdwFlags))
                    {
                        throw new Exception();
                    }
                    byte[] result = new byte[outputSize];
                    Marshal.Copy(nativeBuffer, result, 0, outputSize);
                    return result;
                }
                finally { if (IntPtr.Zero != nativeBuffer) { Marshal.FreeCoTaskMem(nativeBuffer); } }
            }

            internal static string Encode(byte[] input, CrypBinaryFlags flags,
                Encoding encoding)
            {
                int output_size = 0;
                byte[] result = null;
                _Encode(input, input.Length, ref result, ref output_size, flags, true, false);
                result = new byte[output_size];
                _Encode(input, input.Length, ref result, ref output_size, flags, false, false);
                return encoding.GetString(result);
            }

            private static void _Encode(byte[] input, int input_size, ref byte[] output,
              ref int output_size, CrypBinaryFlags flags, bool get_only_size,
              bool alloc_buffer)
            {
                if (get_only_size)
                {
                    output_size = 0;
                    output = null;
                }
                else
                {
                    if (alloc_buffer)
                    {
                        output = new byte[output_size];
                    }
                }
                if (!CryptBinaryToString(input, input_size, flags, output, ref output_size))
                {
                    throw new Exception();
                }
            }
        }
        static void Main(string[] args)
        {
            var bytes = new byte[] { 0x11, 0x22, 0x33, 0x44 };
            var encoded = CryptoApi.Encode(bytes, CryptoApi.CrypBinaryFlags.RawHexadecimal, Encoding.UTF8);
            Console.WriteLine(encoded);
            Console.ReadKey();
            var decoded = CryptoApi.Decode(encoded, CryptoApi.CrypBinaryFlags.RawHexadecimal, encoded.TrimEnd('\0', '\n', '\r').Length);
            Console.WriteLine(string.Join(" ", decoded.Select(p=>p.ToString("x2"))));
            Console.ReadKey();

        }
    }
}


Сообщение было отредактировано: 5 апр 21, 17:36
5 апр 21, 17:43    [22304686]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
hVostt
Member

Откуда:
Сообщений: 19144
jenya7
а как мне красиво передать массив байт (byte[] data) одним аргументом?


Ссылкой на файл, где лежит ваш массив байт.

Сообщение было отредактировано: 5 апр 21, 22:07
5 апр 21, 22:15    [22304817]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
hVostt
Member

Откуда:
Сообщений: 19144
Roman Mejtes,

Зачем этот изврат? :)
Зачем вообще WinAPI, эт ж колхоз.
5 апр 21, 22:16    [22304818]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6154
hVostt
Зачем вообще WinAPI, эт ж колхоз.

Колхоз-не колхоз, иногда без WinAPI не обойтись, но в данном случае это просто в разы затратнее и медленнее - маршаллинг между managed/unmanaged+как я сильно подозреваю, поскольку crypt32.dll, то в преобразованиях там участвуют какие-нибудь криптоалгоритмы (даже если ничего не шифруется), а эти алгоритмы быстрыми не были никогда.
public class Program
{
  static void Main()
  {
    BenchmarkRunner.Run<Program>();
  }


  [Benchmark]
  public void CharArrayEncode()
  {
    _ = ToHexString(GetBytes());
  }

  [Benchmark]
  public void HexStringTableEncode()
  {
    _ = ToHexString2(GetBytes());
  }

  [Benchmark]
  public void EnumerableDecode()
  {
    var value = ToHexString2(GetBytes());
    _ = Enumerable.Range(0, value.Length)
      .Where(x => x % 2 == 0)
      .Select(x => Convert.ToByte(value.Substring(x, 2), 16))
      .ToArray();
  }

  [Benchmark]
  public void CryptoApiTestEncode()
  {
    _ = CryptoApi.Encode(GetBytes(), CryptoApi.CrypBinaryFlags.RawHexadecimal, Encoding.UTF8);
  }

  [Benchmark]
  public void CryptoApiTestDecode()
  {
    var value = CryptoApi.Encode(GetBytes(), CryptoApi.CrypBinaryFlags.RawHexadecimal, Encoding.UTF8);
    _ = CryptoApi.Decode(value, CryptoApi.CrypBinaryFlags.RawHexadecimal, value.TrimEnd('\0', '\n', '\r').Length);
  }

  static byte[] GetBytes()
  {
    var rnd = new Random((int)DateTime.Now.Ticks);
    var values = new byte[1024];
    rnd.NextBytes(values);
    return values;
  }

  static string ToHexString(byte[] value)
  {
    var length = value.Length;
    if (length == 0)
      return string.Empty;
    if (length > (int.MaxValue / 2))
      throw new InvalidOperationException($"Length exceeded {int.MaxValue / 2} value");
    var chArrayLength = length * 2;
    var chArray = new char[chArrayLength];
    var index = 0;
    for (var i = 0; i < chArrayLength; i += 2)
    {
      var b = value[index++];
      chArray[i] = GetHexValue(b / 16);
      chArray[i + 1] = GetHexValue(b % 16);
    }
    return new string(chArray, 0, chArray.Length);
  }

  static char GetHexValue(int i)
  {
    if (i < 10)
      return (char)(i + '0');
    return (char)(i - 10 + 'A');
  }

  static readonly string[] hexStringTable = 
  {
    "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
    "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
    "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
    "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
    "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
    "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
    "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
    "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
    "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
    "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
    "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
    "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
    "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
    "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
    "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
    "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
  };

  static string ToHexString2(byte[] value)
  {
    var sb = new StringBuilder();
    foreach (var b in value)
      sb.Append(hexStringTable[b]);
    return sb.ToString();
  }
}


|               Method |      Mean |    Error |   StdDev |
|--------------------- |----------:|---------:|---------:|
| CharArrayEncode | 12.51 us | 0.211 us | 0.207 us |
| HexStringTableEncode | 11.35 us | 0.058 us | 0.054 us |
| EnumerableDecode | 76.79 us | 0.437 us | 0.409 us |
| CryptoApiTestEncode | 141.76 us | 0.912 us | 0.853 us |
| CryptoApiTestDecode | 425.25 us | 2.204 us | 1.954 us |

- при этом способ декодирования строки в байты в EnumerableDecode был взят навскидку самый простейший, есть более оптимальные: https://stackoverflow.com/questions/14332496/most-light-weight-conversion-from-hex-to-byte-in-c
6 апр 21, 07:38    [22304874]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
hVostt
Member

Откуда:
Сообщений: 19144
Сон Веры Павловны
Колхоз-не колхоз, иногда без WinAPI не обойтись


В данном случае вообще непонятно нафига тут WinAPI.
6 апр 21, 08:50    [22304892]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4159
hVostt
Сон Веры Павловны
Колхоз-не колхоз, иногда без WinAPI не обойтись


В данном случае вообще непонятно нафига тут WinAPI.

да слону понятно, что табличный метод самый быстрый и тривиальный, я же не спорю. - способ с WinAPI еще плох и в том, что core это просто дохлый номер :(

вообще последний раз, когда я юзал winapi это было чтения INI файлов. причем библиотека эта была со времен win31 =)
просто вспомнил, что в crypt32 было подобное, что нужно автору
6 апр 21, 16:37    [22305115]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
fkthat
Member

Откуда:
Сообщений: 4642
Хм... А по-старинке просто пайпом через stdio? Или такое это сейчас уже считается старперством? :))
9 апр 21, 19:59    [22306733]     Ответить | Цитировать Сообщить модератору
 Re: Передать массив байт в консольную апликацию.  [new]
iskatelsql
Member

Откуда:
Сообщений: 840
ХМХО все - таки файл...

Если твоя консольная заточена исключительно на работу с другой программой, которая ей будет передавать, то вообще без разницы. А если она сколько-нибудь универсальная, и предполагает ввод вручную или из командных файлов... То тебе потребуется доп программа и доп время, чтоб перевести файл в кодировку и подать на ввод. Лишние телодвижения не очень красивы.

Сообщение было отредактировано: 10 апр 21, 22:43
10 апр 21, 22:50    [22307122]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить