![]() |
|
Преобразовать String в byte array | ☑ | ||
---|---|---|---|---|
0
detec
01.06.11
✎
13:00
|
Приветствую!
С библиотеки CAPICOM перехожу на .NET-овский класс System.Security.Cryptography.SHA1CryptoServiceProvider, рассчитываю MD5. Раньше с помощью ADODB.Stream читал нужный мне файл как бинарный поток и на выходе получал тип String, определяемый как COMSafeArray в отладчике. System.Security.Cryptography.SHA1CryptoServiceProvider в методе ComputeHash хочет либо Stream, либо byte array. Кто-то знает, как можно с помощью конструкции Новый COMОбъект преобразовать полученный String в byte array?? Важно! Нельзя использовать Javascript'ные вставки, т.к. код должен работать под x64. |
|||
1
Лефмихалыч
01.06.11
✎
13:05
|
а ADODB.Stream туда нельзя прямо как есть всунуть?
|
|||
2
detec
01.06.11
✎
13:12
|
(1) пробовал, не даёт.
|
|||
3
detec
01.06.11
✎
13:13
|
Сейчас сменил класс на более подходящий System.Security.Cryptography.MD5CryptoServiceProvider, но там тоже требуется byte array или stream.
|
|||
4
Serginio1
01.06.11
✎
14:07
|
А что, мешает написать Сом сервер на Net, который бы вернул тебе строку?
|
|||
5
H A D G E H O G s
01.06.11
✎
14:09
|
Что мешает разобрать строку на массив байт в 1С и запихать его в comsafearray ?
|
|||
6
H A D G E H O G s
01.06.11
✎
14:09
|
ComSafeArray на то и ComSafeArray, чтобы через него обмениваться.
|
|||
7
H A D G E H O G s
01.06.11
✎
14:10
|
COMSafeArray (COMSafeArray)
COMSafeArray (COMSafeArray) Методы: GetDimensions (GetDimensions) GetLength (GetLength) GetLowerBound (GetLowerBound) GetType (GetType) GetUpperBound (GetUpperBound) GetValue (GetValue) IsResizable (IsResizable) Resize (Resize) SetValue (SetValue) Выгрузить (Unload) Конструкторы: Из COMSafeArray Из массива 1 Из массива 2 По типу элемента 1 По типу элемента 2 Описание: Объектная оболочка над многомерным массивом SAFEARRAY из COM. Позволяет создавать и использовать SAFEARRAY для обмена данными между COM-объектами. Для передачи массива в качестве параметра метода COM-объекта необходимо построить COMSafeArray нужной размерности с нужным типом элемента и указать построенный COMSafeArray в качестве значения входного параметра. Другие объекты 1С:Предприятия можно использовать в качестве значений входных параметров типа Массив только при наличии исчерпывающей информации о типах параметров в библиотеке типа COM-объекта. Результат метода COM-объекта или значение выходного параметра типа Массив всегда представляется объектом COMSafeArray. Пример: Массив = Новый COMSafeArray("VT_I4", 2); Массив.SetValue(0, 23); Массив.SetValue(1, 13.5); COMОбъект = Новый COMObject("ExampleCOMObject.ECOMClass"); COMОбъект.ProcessSafeArray(Массив); |
|||
8
Serginio1
01.06.11
✎
14:14
|
Согласен, только ему нужен VT_I1
|
|||
9
H A D G E H O G s
01.06.11
✎
14:15
|
(8) Это из примера СП.
|
|||
10
Serginio1
01.06.11
✎
14:28
|
Кстати был ыесьма удивлен, когда
public object CreateArray(string type, int length) { return new AutoWrap(Array.CreateInstance(Type.GetType(type), length)); } (AutoWrap это оболочка IRflect) вотображается в 1С как COMSafeArray |
|||
11
detec
01.06.11
✎
14:35
|
(5)
У меня уже есть возвращённый COMSafeArray. Я смотрел в отладчике - там массив с числами, я так понимаю, байтами. По идее, массив с байтами. CAPICOM на входе в метод шифрования требует тип String, и мой COMSafeArray ошибок не вызывал. Возможно, всё дело в 8.2.14. Тут где-то пробегала тема, что в 8.2 что-то ухудшили именно в работе с .NET. (10) AutoWrap - есть вариант этой компоненты под x64? |
|||
12
H A D G E H O G s
01.06.11
✎
14:35
|
(11) ЧТО мешает составить строку из байт?
|
|||
13
H A D G E H O G s
01.06.11
✎
14:36
|
Данные="";
Для i=0 По Массив.Количество()-1 Цикл Данные=Данные+Символ(Массив[i]); КонецЦикла; |
|||
14
detec
01.06.11
✎
14:42
|
(13)
Спасибо, сейчас попробую. У меня код String.GetType() возвращает "VT_UI1", где String - COMSafeArray, полученный из Стрим.Read(). |
|||
15
detec
01.06.11
✎
14:46
|
Нет, к сожалению, код с передачей переменной Данные из (13) не взлетает ((
|
|||
16
H A D G E H O G s
01.06.11
✎
14:48
|
(15) Что пишет?
|
|||
17
detec
01.06.11
✎
14:54
|
(16) пишет "неизвестная ошибка".
Я сейчас попробую сделать свой новый COMSafeArray, как описано в (7) и (8). Если я правильно понимаю, в изначально выгруженном COMSafeArray байты "неправильного" типа. |
|||
18
H A D G E H O G s
01.06.11
✎
15:02
|
байты "неправильного" типа
как сказанул!!! |
|||
19
Serginio1
01.06.11
✎
15:13
|
(11) Нет Это враппер для преобразования Net объектов в IDispatch v8: Объекты Net в IDispatch
|
|||
20
detec
01.06.11
✎
15:16
|
(18) )))
А теперь не могу заполнить новосозданный массив String = СтруктураШифрования.Стрим.Read(); Массив = Новый COMSafeArray("VT_I1", String.getLength()); Для н = 0 По String.getLength() - 1 Цикл Массив.SetValue(н, String.getValue(н)); КонецЦикла; Спотыкается на 1-м элементе, String.getValue(н) у меня в отладчике показывает тип "число", 255. Я пробовал жёстко вставлять значения в новый COMSafeArray, равные 0; 1; 5. Когда попробовал вставить символ - выругалось в несоответствие типов. Грешу уже на платформу - использую 8.2.14.460. |
|||
21
Serginio1
01.06.11
✎
15:17
|
(19)+ Авыполняться будет взависимоти от среды
|
|||
22
detec
01.06.11
✎
15:19
|
(19) спасибо. Если ничего не поможет - попробую скомпилировать код из той темы под x64.
|
|||
23
Serginio1
01.06.11
✎
15:21
|
(20) У тебя уникоде. Поэтому нужно брать % 255 и сдвиг на 8 байт то есть делить на 256,
|
|||
24
Serginio1
01.06.11
✎
15:23
|
Но вообще можешь попробоать в VT_UI2 по идее он должен кастнуть.
|
|||
25
Serginio1
01.06.11
✎
15:24
|
Компилируй под any процессор
|
|||
26
H A D G E H O G s
01.06.11
✎
15:25
|
(23) Причем тут уникод?
Он числа вставляет. |
|||
27
Serginio1
01.06.11
✎
15:26
|
(26) в уникоде сколько байтов?
|
|||
28
H A D G E H O G s
01.06.11
✎
15:28
|
(27) 2, 4, 8?.
|
|||
29
Serginio1
01.06.11
✎
15:29
|
(22) Тольк регасмь из по 64
@"Microsoft.NET\Framework64\v4.0.30319\regasm.exe"; с ключом /codebase |
|||
30
Serginio1
01.06.11
✎
15:30
|
(28) 2 байта то есть до 64 с чем то, в байте макс значеие 255
|
|||
31
H A D G E H O G s
01.06.11
✎
15:30
|
Скажите мне тока, почему "VT_I1", а не "VT_UI1"
|
|||
32
H A D G E H O G s
01.06.11
✎
15:31
|
(30) ППЦ.
2, 4, возможно 8 байт на символ (для иероглифов каких-нибудь). Че не понятного? Про 8 байт - не в курсе. |
|||
33
H A D G E H O G s
01.06.11
✎
15:33
|
(30) 65536 вариантов (символов). Поражен, это еще при работе с памятью в бейсике (сегмент:смещение) должно отложиться было.
|
|||
34
Serginio1
01.06.11
✎
15:33
|
(32) а всовываешь ты 2 байтное значение в однобайтное
|
|||
35
H A D G E H O G s
01.06.11
✎
15:34
|
(34) Он всовывает ЧИСЛО!
<<А теперь не могу заполнить новосозданный массив String = СтруктураШифрования.Стрим.Read(); Массив = Новый COMSafeArray("VT_I1", String.getLength()); Для н = 0 По String.getLength() - 1 Цикл Массив.SetValue(н, String.getValue(н)); КонецЦикла; Спотыкается на 1-м элементе, String.getValue(н) у меня в отладчике показывает тип "число", 255.>> |
|||
36
Serginio1
01.06.11
✎
15:34
|
(32) а зачем если это 2 сдвиг влево на 16 -1. Я только так запоминаю. И чего ты завелся?
|
|||
37
Serginio1
01.06.11
✎
15:35
|
(34 оторое либо обрезано до 255 либо выдаст ошибку если код символа больше 255
|
|||
38
H A D G E H O G s
01.06.11
✎
15:36
|
Бекоурз, он всовывает значение 255 в знаковую ячейку. Возможно "умный" обработчик COM объектов и говорит - "не больше 128 в меня влезет. И знак.".
Поэтому (31). |
|||
39
H A D G E H O G s
01.06.11
✎
15:37
|
(36) Я - спокоен. Скучно.
|
|||
40
H A D G E H O G s
01.06.11
✎
15:37
|
(38) 128->127
|
|||
41
H A D G E H O G s
01.06.11
✎
15:39
|
Хотяяяя. Автор! Ты где?
|
|||
42
Serginio1
01.06.11
✎
15:39
|
(38) Да для VT_I1 128 вроде исключение.
|
|||
43
detec
01.06.11
✎
15:40
|
Можно по-простому объяснить разницу между VT_I1, VT_UI1 и другими типами, которые провзучали в ветке?
|
|||
44
Serginio1
01.06.11
✎
15:42
|
(43) Знаковый и безнаковые. Не знаю что у тебя представляет
СтруктураШифрования, но она однозначно беззнаковая, но если у нее есть символы больше 255 то данное значение либо обрежется, либо вызовет исключение. |
|||
45
H A D G E H O G s
01.06.11
✎
15:43
|
У меня при попытке
мас=Новый COMSafeArray("VT_I1",1); мас.SetValue(0,255); Ошибка при вызове метода контекста (SetValue): Выход за пределы диапазона. мас=Новый COMSafeArray("VT_UI1",1); мас.SetValue(0,255); Срабатывает мас=Новый COMSafeArray("VT_I1",1); мас.SetValue(0,127); Срабатывает ЧЯДНТ? |
|||
46
H A D G E H O G s
01.06.11
✎
15:44
|
(44) Исключение. У него тупо однобайтный массив походу.
|
|||
47
detec
01.06.11
✎
15:46
|
Массив.SetValue(н, 127);
Отрабатывает. Не отрабатывает Массив.SetValue(н, 128); и выше. |
|||
48
detec
01.06.11
✎
15:47
|
(45) Да-да, именно такая ошибка. Придётся тупо перебирать типы.
|
|||
49
H A D G E H O G s
01.06.11
✎
15:48
|
**facepalm
|
|||
50
H A D G E H O G s
01.06.11
✎
15:48
|
Измени
Массив = Новый COMSafeArray("VT_I1", String.getLength()); на Массив = Новый COMSafeArray("VT_UI1", String.getLength()); |
|||
51
detec
01.06.11
✎
15:52
|
(50) Переделал, новый COMSafeArray заполняется. Но класс .NET выдаёт Неизвестная ошибка.
|
|||
52
H A D G E H O G s
01.06.11
✎
15:55
|
(51) Ну, а что ему (NET-классу надо то)?
|
|||
53
detec
01.06.11
✎
15:56
|
Может нужно заполнить новый массив символами ASCII? Ведь код Массив.SetValue(н, Символ(String.getValue(н))) по идее, даст символы в Unicode.
.NET класс требует для функции ComputeHash(Byte()) Computes the hash value for the specified byte array. |
|||
54
H A D G E H O G s
01.06.11
✎
15:59
|
(53) ППЦ.
http://msdn.microsoft.com/ru-ru/library/s02tk69a.aspx Ну вот где там написано, что он comsafearray сожрет, этот ComputeHash() ? Там, в компоненте, надо вырезать данные из переданного comsafearray и сделать на их основе System.Byte() |
|||
55
Serginio1
01.06.11
✎
16:01
|
(53) 45 правильно он начинает кастить по значению, а не по физическому расположению битов как в нормальных языках.
|
|||
56
detec
01.06.11
✎
16:03
|
(54) Это я видел. Можно как-то в 1С 8 сделать аналог
' Convert the input string to a byte array and compute the hash. Dim data As Byte() = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input)) ? |
|||
57
detec
01.06.11
✎
16:05
|
(55) Можно по-русски или по 1С-ному ))) ?
|
|||
58
Serginio1
01.06.11
✎
16:13
|
(57) Не суть (что знаковый байт что беззнаковый это 8 бит). Я так понимаю СтруктураШифрования.Стрим.Read(); возвращает safearray() VT_UI1 Посмотри в отладчике.
По идее ты его и должен обратно передать. А проще написать ком сервер и сделать все, что ты хочешь без переконвертаций структур |
|||
59
Serginio1
01.06.11
✎
16:17
|
Или воспользуйся моей приблудой. По идее должно получиться.
|
|||
60
detec
01.06.11
✎
16:18
|
(58) Да, отладчик показывает именно это.
С нестандартными компонентами я зарёкся работать. У меня x64 и платформа 8.2.14. Код должен отрабатывать как в x32, так и при исполнении на 64-битном сервере 1С:Предприятие. С NativeAPI-компонентами, как я понял, глухо, как в танке. (59) спасибо. |
|||
61
Serginio1
01.06.11
✎
16:21
|
(60) У тебя нетовский код скомпилированный под any процессор будет работать под любой платформой. При этом если ты COM сервер нужно зарегить как по 64 @"Microsoft.NET\Framework64\v4.0.30319\regasm.exe";
с ключом /codebase так и под обычным регасмом. Все это прекрасно работает на сервере. И никаких C Native API не надо |
|||
62
Serginio1
01.06.11
✎
16:29
|
(60) Я у себя вызываю метод
SearchDetailItem[] DetailSearch(string APIkey, string[] PartNumbers, string ChangePart) Вызываю его Массивассив=объект.СоздатьМассив("System.String",1); Массив.SetValue(Артикул,0); резулт=Езоко.DetailSearch("ЧЧЧЧЧЧЧЧЧ",массив,"No"); для Каждого стр из резулт цикл ........ КонецЦикла; Внутри каждый объект обернут через AutoWrap |
|||
63
detec
01.06.11
✎
18:17
|
Рассказываю, как я решил эту задачу. ))
Есть у MS такая утилитка как Microsoft File Checksum Integrity Verifier (FCIV) Utility Простейший синтаксис, консольный режим - и программулина выдаёт хэш MD5. Я добавил её в общие макеты, а при необходимости вычислить хэш - программно вызываю через COM-объект командную строку, считываю консольный вывод и регулярным выражением вытягиваю хэш. Благо, наработки по сабджу были. А так как код выполняется на севрере 1С:Предприятие - нет никаких выпрыгивающих чёрных окошек. И не нужно трахать мозги всякими компонентами и преобразованиями, x32, x64. |
|||
64
H A D G E H O G s
01.06.11
✎
18:23
|
(63) Мдать.
|
|||
65
H A D G E H O G s
01.06.11
✎
18:24
|
Даже в дремучем Дельфи 6 есть типовая компонента получения MD5.
Там делов написать ВК, либо COMсервер на 15 минут. |
|||
66
H A D G E H O G s
01.06.11
✎
18:24
|
Вот те делать нечего.
|
|||
67
Serginio1
01.06.11
✎
18:28
|
(63) Не знаю, у меня нет никаких проблем с черными окошками (Это когда сервер долго занят? помню было такое и писал приложение которое гасило это окошко) и x32, x64.
Так или иначе в итоге ты используешь ком объект. Используй обертку нетовских объектов. Правда нужно там дописать GetType с именем http://msdn.microsoft.com/ru-ru/library/z7aahsb8.aspx или http://msdn.microsoft.com/ru-ru/library/system.reflection.assembly.gettype.aspx |
|||
68
detec
01.06.11
✎
18:30
|
(64) Это всё классно, если где-то стоит установленная IDE, есть навыки программирования на этом языке, какие-то базовые знания.
А когда есть отлаженная лично библитоечка функций, то проще добавить в конкретную конфу несколько функций. Мне приходилось работать с консольными утилитами, альтернативы которым просто не было, и только регулярными выражениями можно было пропарсить их ответ и вернуть результат в 1С. Но спасибо вам за помощь, ребята. Много нового узнал. Чёрное окошко - это когда вызываешь из 1С:Предприятие wscript.shell - чёрное окошко командной строки. Видно только при запуске с клиента или в файловой базе. |
|||
69
Serginio1
01.06.11
✎
18:30
|
(65) Да изменил я Delphi. В основном Net. И связано это в том числе и с написанием приложений для КПК. Да и если честно, NET развивается семимильными шагами
|
|||
70
Serginio1
01.06.11
✎
18:41
|
(68) Изучай. Пригодиться однозначно.
|
|||
71
Serginio1
02.06.11
✎
12:28
|
Исправил посмотри новый вариант с примером
Пример использования объект=Новый COMОбъект("NetObjectToIDispatch"); Типмд5= объект.ПолучитьТип("System.Security.Cryptography.MD5CryptoServiceProvider",""); Активатор=объект.Activator; мд5=Активатор.CreateInstance(Типмд5); типЭнкодинг=объект.ПолучитьТип("System.Text.Encoding",""); рез=мд5.ComputeHash(типЭнкодинг.Default.GetBytes("Строка")); для каждого стр из рез Цикл Сообщить(стр); КонецЦикла; |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |