Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/29: Рейтинг темы: голосов - 29, средняя оценка - 4.69
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484

Оценка кода

28.01.2020, 22:43. Показов 6518. Ответов 123
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, прошу вас всех оценить мой код , по возможности дать советы что так , а что не так и как это исправить либо в каком направлении смотреть , это моя первая попытка создать что-то не ради забавы , а чтобы использовать это в реальной жизни. Сразу скажу что еще не все доделал что хотел бы. Это декодер asn1.der , данные передаются в decode() в виде BLOB конвертированного в массив знаков.
header
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include "string.h"
 
#define ENDOFARRAY -1
 
#define INTEGER 0x02
#define OCTET_STRING 0x04
#define OBJECT_IDENTIFIER 0x06
#define SEQUENCE 0x30
 
#define SETBIT(number,bit) ((number) |= (pow(2,bit)))
#define CHECKBIT(number,bit) ((number) & (1 << (bit)))
 
class decoder{
    public:
        decoder();
 
        ~decoder();
 
        char * decode(const unsigned char * ,int,char * cipherT = nullptr, char * Other = nullptr);
 
        void decode64(const char * ,char * cipherT = nullptr, char * Other = nullptr);
 
    private:
        //Calculates number in power
        int pow(int,int);
 
        char* IntToHexChar(int);
 
        void AppendOctetString(int);
 
        int CalculateLongSID(int&);
 
        //Calculates all decimal values of indentifier
        void CalculateIdentifier(int);
 
        //Calculates first byte of indentifier which is decoded to two values
        void CalculateIdentifierFirstByte();
 
        //Convert byte array to decimal value
        int CalculateBytes(int);
 
        //Decoding encoded ans1.der string
        void ParseData();
 
        //Appends passed array with new array
        char * Append(char *,char *);
 
        //Decodes length of front bytes
        int ParseLength(int);
 
        //Handles Octet String
        void OctetStringHandler();
 
        //Handles Object Indentifier
        void ObjectIdentifierHandler();
 
        //Handles Integer
        void IntegerHandler();
 
        //Handles Sequance
        void SequenceHandler();
 
        //Converts char array to int array
        void ToIntArray();
 
        //Copies value of passed array and returns new created one with same values
        const unsigned char *  NewArr(const unsigned char* );
 
        //Byte array as integers
        int * IntByteArray = nullptr;
 
        //Pointer to IntByteArray which is used to move through array
        int * pArr = nullptr;
 
        //Byte array as char
        const unsigned char * CharByteArray = nullptr;
 
        //The result decoded string
        char * Result = new char[1]{};
 
        //Size of IntByteArray
        int size = 0;
};

cpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#include "asn1der.h"
 
decoder::decoder(){
}
 
 
decoder::~decoder(){
    if(CharByteArray)
        delete[] CharByteArray;
    if(IntByteArray)
        delete[] IntByteArray;
}
 
 
char * decoder::Append(char * dst,char * src){  
     int dstlen = strlen(dst),srclen =  strlen(src);
     char* temp = new char[dstlen+srclen+1]{};
     memcpy(temp, dst, dstlen);
     strcat(temp,src);
     delete[] dst;
     return temp;
}
 
 
const unsigned char *  decoder::NewArr(const unsigned char* arr) {
    unsigned char * temp = new unsigned char[size+1]{};
    for(int i = 0;i < size;++i){
        temp[i] = arr[i];
    }
    return temp;
}
 
 
void decoder::ToIntArray(){
    IntByteArray = new int[size+1]{};
    for(int i = 0;i<size;++i){
        IntByteArray[i] = (unsigned int)CharByteArray[i];
    }
    IntByteArray[size] = -1;
    pArr = IntByteArray;
}
 
 
void decoder::ParseData(){
    switch (*pArr)
    {
        case ENDOFARRAY:
            break;
        case INTEGER:
            IntegerHandler();
            ParseData();
            break;
        case OCTET_STRING:
            OctetStringHandler();
            ParseData();
            break;
        case OBJECT_IDENTIFIER:
            ObjectIdentifierHandler();
            ParseData();
            Result = Append(Result,const_cast<char *>("}"));
            break;
        case SEQUENCE:
            SequenceHandler();
            ParseData();
            Result = Append(Result,const_cast<char *>("\n}"));
            break;
        default:
            break;
    }
}
 
 
char * decoder::decode(const unsigned char * Text,int length,char * cipherT, char * Other){
    size = length;
      CharByteArray = NewArr(Text);
      ToIntArray();
      try{
          ParseData();
      }
      catch(const char* exception){
         std::cout << exception;
          return nullptr;
      }
      return Result;
}
 
 
int decoder::ParseLength(int num){
    num &= 63;
    return num;
}
 
 
int decoder::pow(int num, int times){
    if(times == 0)
        return 1;
    if(times == 1)
        return 2;
    if(times > 1)
        return num*pow(num,--times);
}
 
 
int decoder::CalculateBytes(int len){
    int calculated = 0,power = len*8-1;
    for(int i = 0;i < len && ++pArr;i++){
 
        if(*pArr == -1 )
            throw "CalculateBytes error";
 
        for(int q = 7;q >= 0;--q){
            if(CHECKBIT(*pArr,q)){
                calculated += pow(2,power);
            }
            --power;
        }
    }
    return calculated;
}
 
 
void decoder::CalculateIdentifierFirstByte(){ //there are only three types of first node 1,2,3 , first byte is calculated with (firstnode*40 + secondnode)
    if(*++pArr < 80){ //if first byte is less than 80 it means that first node is 1
 
        if(*pArr == -1 )
            throw "CalculateIndentifierFirstByte error";
 
        Result = Append(Result,const_cast<char *>((std::to_string(1) + ".").c_str()));
        Result = Append(Result,const_cast<char *>((std::to_string(*pArr-40)+ ".").c_str())); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else if (*pArr < 120) //means that first node is 2
    {
        Result = Append(Result,const_cast<char *>((std::to_string(2) + ".").c_str()));
        Result = Append(Result,const_cast<char *>((std::to_string(*pArr-80)+ ".").c_str())); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else // first node is 3
    {
        Result = Append(Result,const_cast<char *>((std::to_string(3) + ".").c_str()));
        Result = Append(Result,const_cast<char *>((std::to_string(*pArr-120)+ ".").c_str()));
        return;
    }
}
 
 
int decoder::CalculateLongSID(int& size) {
  int length = 1, value = 0, SID = 0;
  for (;; ++pArr) {
    if (!CHECKBIT(*pArr, 7)) {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      break;
    }
    else
    {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      value = value << 8;
    }
  }
  for (int i = 0; i < length*8-1; ++i) {
    if(CHECKBIT(value,i)){
        SETBIT(SID,i-i/8);
    }
  }
  size += length-2;
  return SID;
 
}
 
 
void decoder::CalculateIdentifier(int len){
    CalculateIdentifierFirstByte();
    for(int i = 0; i<len && ++pArr ; ++i){
        if(*pArr == -1 || *(pArr+1) == -1)
            throw "CalculateIndentifier error";
        if(!CHECKBIT(*pArr,7)){ //if decimal number consists of only one byte
            Result = Append(Result,const_cast<char *>((std::to_string(*pArr) + ".").c_str()));
        }else //if bit 7 is set it means that length of decimal number in bytes is bigger than one byte
        {
            Result = Append(Result,const_cast<char *>((std::to_string(CalculateLongSID(i)) + ".").c_str()));
        }
    }
}
 
 
char * decoder::IntToHexChar(int number){
    char * hex = new char[3]{};
    int num = number/16;
    for(int i = 0;i < 2;++i)
    switch (num)
    {
    case 15:
        hex[i] = 'F';
        num = number%16;
        break;
    case 14:
        hex[i] = 'E';
        num = number%16;
        break;
    case 13:
        hex[i] = 'D';
        num = number%16;
        break;
    case 12:
        hex[i] = 'C';
        num = number%16;
        break;
    case 11:
        hex[i] = 'B';
        num = number%16;
        break;
    case 10:
        hex[i] = 'A';
        num = number%16;
        break;
    case 9:
        hex[i] = '9';
        num = number%16;
        break;
    case 8:
        hex[i] = '8';
        num = number%16;
        break;
    case 7:
        hex[i] = '7';
        num = number%16;
        break;
    case 6:
        hex[i] = '6';
        num = number%16;
        break;
    case 5:
        hex[i] = '5';
        num = number%16;
        break;
    case 4:
        hex[i] = '4';
        num = number%16;
        break;
    case 3:
        hex[i] = '3';
        num = number%16;
        break;
    case 2:
        hex[i] = '2';
        num = number%16;
        break;
    case 1:
        hex[i] = '1';
        num = number%16;
        break;
    case 0:
        hex[i] = '0';
        num = number%16;
        break;
    default:
        break;
    }
    return hex;
}
 
 
void decoder::AppendOctetString(int length){
     for(int i = 0; i < length && ++pArr;++i){
         char * p = IntToHexChar(*pArr);
         Result = Append(Result,p);
         delete[] p;
     }
}
 
 
void decoder::OctetStringHandler(){
    if(!CHECKBIT(*++pArr,7)){
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result,const_cast<char *>(" Octet String : { "));
        AppendOctetString(ParseLength(*pArr));
        Result = Append(Result,const_cast<char *>("}"));
    }
    ++pArr;
}
 
 
void decoder::ObjectIdentifierHandler(){
    Result = Append(Result,const_cast<char *>(" OBJECT INDENTIFIED WITH VALUE: { "));
    if(!CHECKBIT(*++pArr,7)){ //if length in one byte
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        CalculateIdentifier(*pArr-1);
    }
    else //behaviour not described
    {
        CalculateIdentifierFirstByte();
        CalculateIdentifier(ParseLength(*pArr));
    }
    ++pArr;
}
 
 
void decoder::IntegerHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result,const_cast<char *>(" INTEGER WITH VALUE: { "));
        Result = Append(Result, const_cast<char *>((std::to_string(CalculateBytes(ParseLength(*pArr)))+ " }").c_str()));
    }
    else
    {
        Result = Append(Result,const_cast<char *>(" INTEGER WITH VALUE: { "));
        Result = Append(Result, const_cast<char *>((std::to_string(CalculateBytes(CalculateBytes(ParseLength(*pArr))))+ " }").c_str()));
    }
    ++pArr;
}
 
 
void decoder::SequenceHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
            if(*pArr == -1 )
                throw "SequenceHandler error";
 
            Result = Append(Result,const_cast<char *>(" SEQUENCE WITH LENGTH: "));
            Result = Append(Result, const_cast<char *>((std::to_string(*pArr) + "{ \n\t").c_str()));
      }
    else
    {
        Result = Append(Result,const_cast<char *>(" SEQUENCE WITH LENGTH: "));
        Result = Append(Result, const_cast<char *>((std::to_string(CalculateBytes(ParseLength(*pArr)))+ "\n\t").c_str()));
    }
    ++pArr;
}
 
 
void decoder::decode64(const char * Text,char * cipherT, char * Other){
    
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.01.2020, 22:43
Ответы с готовыми решениями:

Советы по ускорению работы кода + оценка самого кода
Вчера вечером сел написать 3 консольные программки для работы с шаблонами размножения текста: 1.Выборка групп синонимов(создание словаря)...

Оценка кода
Добрый день! Есть задание в ВУЗе: Я сделал следующий код: #include &lt;iostream&gt; #include &lt;conio.h&gt; int...

Оценка кода
Суть задачи описал вначале кода, хотелось бы услышать, что можно было сделать лучше, где можно было бы написать/описать...

123
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
28.01.2020, 22:58
ReYalp, в чем причина отказа от std::vector?
Зачем столько const_cast?
Можно же изменить сигнатуру decoder::Append, добавив const к указателю источнику.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.01.2020, 22:59
Цитата Сообщение от ReYalp Посмотреть сообщение
Здравствуйте, прошу вас всех оценить мой код , по возможности дать советы что так , а что не так и как это исправить либо в каком направлении смотреть , это моя первая попытка создать что-то не ради забавы , а чтобы использовать это в реальной жизни.
Тебе не кажется, что в IntToHexChar лучше использовать массив, вместо switch?
1
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
28.01.2020, 23:01
вместо констант через define лучше использовать enum
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
28.01.2020, 23:05  [ТС]
oleg-m1973, вот в этом моменте я не уверен, с массивом будет лучше?

Добавлено через 2 минуты
Max Dark,
Цитата Сообщение от Max Dark Посмотреть сообщение
в чем причина отказа от std::vector?
Зачем столько const_cast?
Можно же изменить сигнатуру decoder::Append, добавив const к указателю источнику.
от вектора причина отказа в том что я хотел просто написать вручную , с вектором было бы в разы легче , я это понимаю, насчет const и действительно) мне почему-то кзалось что strcat не может принимать источник как конст)

Добавлено через 24 секунды
Max Dark,
Цитата Сообщение от Max Dark Посмотреть сообщение
вместо констант через define лучше использовать enum
окей,учту
0
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
28.01.2020, 23:06
Цитата Сообщение от ReYalp Посмотреть сообщение
от вектора причина отказа в том что я хотел просто написать вручную
тогда я бы вынес эту часть в отдельный класс.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
28.01.2020, 23:08  [ТС]
Max Dark, какую именно часть? и как код в общем?
0
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
28.01.2020, 23:20
Цитата Сообщение от ReYalp Посмотреть сообщение
какую именно часть?
ту что занимается динамической памятью: выделение, добавление элементов.
Цитата Сообщение от ReYalp Посмотреть сообщение
и как код в общем?
воздержусь от оценки.

Добавлено через 2 минуты
Цитата Сообщение от ReYalp Посмотреть сообщение
с массивом будет лучше?
В несколько раз короче и без дублирования кода.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
29.01.2020, 00:17
Цитата Сообщение от ReYalp Посмотреть сообщение
Здравствуйте, прошу вас всех оценить мой код , по возможности дать советы что так , а что не так
нет смысла давать оценку кода,
который агрит компиляторы.

https://rextester.com/UCHSH48627


source_file.cpp:15:7: warning: ‘class decoder’ has pointer data members [-Weffc++]
class decoder{
^
source_file.cpp:15:7: warning: but does not override ‘decoder(const decoder&)’ [-Weffc++]
source_file.cpp:15:7: warning: or ‘operator=(const decoder&)’ [-Weffc++]
source_file.cpp: In member function ‘char* decoder::Append(char*, char*)’:
source_file.cpp:100:29: warning: conversion to ‘int’ from ‘size_t {aka long unsigned int}’ may alter its value [-Wconversion]
int dstlen = strlen(dst),srclen = strlen(src);
^
source_file.cpp:100:51: warning: conversion to ‘int’ from ‘size_t {aka long unsigned int}’ may alter its value [-Wconversion]
int dstlen = strlen(dst),srclen = strlen(src);
^
source_file.cpp:102:30: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
memcpy(temp, dst, dstlen);
^
source_file.cpp: In member function ‘void decoder::ToIntArray()’:
source_file.cpp:121:56: warning: use of old-style cast [-Wold-style-cast]
IntByteArray[i] = (unsigned int)CharByteArray[i];
^
source_file.cpp: At global scope:
source_file.cpp:157:69: warning: unused parameter ‘cipherT’ [-Wunused-parameter]
char * decoder::decode(const unsigned char * Text,int length,char * cipherT, char * Other){
^
source_file.cpp:157:85: warning: unused parameter ‘Other’ [-Wunused-parameter]
char * decoder::decode(const unsigned char * Text,int length,char * cipherT, char * Other){
^
source_file.cpp:425:37: warning: unused parameter ‘Text’ [-Wunused-parameter]
void decoder::decode64(const char * Text,char * cipherT, char * Other){
^
source_file.cpp:425:49: warning: unused parameter ‘cipherT’ [-Wunused-parameter]
void decoder::decode64(const char * Text,char * cipherT, char * Other){
^
source_file.cpp:425:65: warning: unused parameter ‘Other’ [-Wunused-parameter]
void decoder::decode64(const char * Text,char * cipherT, char * Other){
^
source_file.cpp: In member function ‘int decoder:ow(int, int)’:
source_file.cpp:185:1: warning: control reaches end of non-void function [-Wreturn-type]
}
Цитата Сообщение от ReYalp Посмотреть сообщение
как это исправить либо в каком направлении смотреть
исправить все деффекты о которых пишет компилятор,
для начала.
3
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
29.01.2020, 00:26  [ТС]
hoggy, как можно включить GCC чтобы он так же "агрился"?

Добавлено через 2 минуты
hoggy, и насчёт ошибок unused parametr я не знаю как их исправить, задумано так что если вызывающе у нужны будут эти переменные он передаст указатель и я когда найду данные верну ему их с помощью указателя, ещё есть такой вопрос, можно как-то проверить указывает ли указатель на динамически выделенную память или статически?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
29.01.2020, 00:46
Цитата Сообщение от ReYalp Посмотреть сообщение
как можно включить GCC чтобы он так же "агрился"?
там по ссылке если пройти,
можно посмотреть командную строку:
Code
1
2
3
-std=c++14 -fopenmp -O2 -g3 
-pedantic -Wall -Weffc++ -Wextra -Woverloaded-virtual -Wctor-dtor-privacy -Wnon-virtual-dtor -Wold-style-cast -Wconversion -Wsign-conversion -Winit-self -Wunreachable-code 
-o a.out source_file.cpp -I/usr/local/include/boost_1_6_0/ -lboost_system -lboost_filesystem
конкретно, тебя интересует часть:
Code
1
-pedantic -Wall -Weffc++ -Wextra -Woverloaded-virtual -Wctor-dtor-privacy -Wnon-virtual-dtor -Wold-style-cast -Wconversion -Wsign-conversion -Winit-self -Wunreachable-code
Цитата Сообщение от ReYalp Посмотреть сообщение
unused parametr я не знаю как их исправить
C++
1
2
3
// второй аргумент в данный момент не используется
// поэтому его имя можно просто не писать
void set_param(const char* name, const size_t);
этот способ мне не нравится, потому что не понятно, что там за параметр
поэтому, я считаю, что лучше писать вот так:

C++
1
2
// не используемое имя закомментированно
void set_param(const char* name, const size_t /*age*/);
иногда бывает нужно не трогать имя параметра
но допустим, временно оно не используется.
тогда можно написать так:

C++
1
2
3
4
5
6
7
void set_param(const char* name, const size_t age);
{
    (void) age; // <--- попросим компилятор не ворчать
 
    check(name);
    ...
}
Цитата Сообщение от ReYalp Посмотреть сообщение
ещё есть такой вопрос, можно как-то проверить указывает ли указатель на динамически выделенную память или статически?
никак.
2
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
29.01.2020, 09:34
Цитата Сообщение от ReYalp Посмотреть сообщение
oleg-m1973, вот в этом моменте я не уверен, с массивом будет лучше?
Ну да, лучше
C++
1
2
3
static const char _digs[] = "01234567890ABCDEF";
.............................................
hex[i] = _digs[num];
2
Just Do It!
 Аватар для XLAT
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,054
Записей в блоге: 3
29.01.2020, 10:06
Цитата Сообщение от ReYalp Посмотреть сообщение
по возможности дать советы что так
по форматированию:
видно, что вы уделяете этому внимание,

но моё личное имхо:
я не люблю ГОРИЗОНТАЛЬНО СКРОЛЛИТЬ.
и причины этому даже больше объективные чем субъективные.
Если сильно много горизонтального скролла это может "также сильно" сказаться и на моей производительности, как кодера.
2
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
29.01.2020, 13:30
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
decoder::~decoder(){
    if(CharByteArray)//Проверки по большому счету, бесполезны
        delete[] CharByteArray;
    if(IntByteArray)
        delete[] IntByteArray;
}
 
char * decoder::decode(const unsigned char * Text,int length,char * cipherT, char * Other){
    size = length;
      CharByteArray = NewArr(Text);//А CharByteArray точно не указывает ни на какой другой кусок?
      //...
}
 
const unsigned char *  decoder::NewArr(const unsigned char* arr) {
    unsigned char * temp = new unsigned char[size+1]{};
    for(int i = 0;i < size;++i){//Почему цикл, а не memcpy?
        temp[i] = arr[i];
    }
    return temp;
}
 
char * decoder::Append(char * dst,char * src){  
     int dstlen = strlen(dst),srclen =  strlen(src);
     char* temp = new char[dstlen+srclen+1]{};
     memcpy(temp, dst, dstlen);
     strcat(temp,src);//можно memcpy(temp + dstlen, src, srclen + 1) причем так можно даже опустить инициализацию в new
     delete[] dst;
     return temp;
}

Цитата Сообщение от hoggy Посмотреть сообщение
(void) age; // <--- попросим компилятор не ворчать
или новомодное
C++
1
2
3
4
void set_param(const char* name, [[maybe_unused]] const size_t age)//; лишняя
{
   //...
}
1
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
30.01.2020, 20:46  [ТС]
hoggy, исправил что советовали и что смог
срр
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#include "asn1der.h"
 
decoder::decoder(){
}
 
decoder::decoder(const decoder& obj){
    this->CharByteArray = obj.CharByteArray;
    this->IntByteArray = obj.IntByteArray;
    this->pArr = obj.IntByteArray;
    this->size = obj.size;
}
 
decoder::~decoder(){
    if(CharByteArray)
        delete[] CharByteArray;
    if(IntByteArray)
        delete[] IntByteArray;
}
 
decoder& decoder::operator=(const decoder& obj){
    this->CharByteArray = obj.CharByteArray;
    this->IntByteArray = obj.IntByteArray;
    this->pArr = obj.IntByteArray;
    this->size = obj.size;
    return *this;
}
 
char * decoder::Append(char * dst,const char * src){  
     unsigned long dstlen = strlen(dst),srclen =  strlen(src);
     char* temp = new char[dstlen+srclen+1];
     memcpy(temp, dst, dstlen);
     memcpy(temp + dstlen, src, srclen + 1);
     delete[] dst;
     return temp;
}
 
 
const unsigned char *  decoder::NewArr(const unsigned char* arr) {
    unsigned char * temp = new unsigned char[size+1]{};
    memcpy(temp,arr,size+1);
    return temp;
}
 
 
void decoder::ToIntArray(){
    IntByteArray = new int[size+1]{};
    for(unsigned int i = 0;i<size;++i){
        IntByteArray[i] = static_cast<unsigned int>(CharByteArray[i]);
    }
    IntByteArray[size] = -1;
    pArr = IntByteArray;
}
 
 
void decoder::ParseData(){
    switch (*pArr)
    {
        case ENDOFARRAY:
            break;
        case INTEGER:
            IntegerHandler();
            ParseData();
            break;
        case OCTET_STRING:
            OctetStringHandler();
            ParseData();
            break;
        case OBJECT_IDENTIFIER:
            ObjectIdentifierHandler();
            ParseData();
            Result = Append(Result,("}"));
            break;
        case SEQUENCE:
            SequenceHandler();
            ParseData();
            Result = Append(Result,("\n}"));
            break;
        default:
            break;
    }
}
 
 
char * decoder::decode(const unsigned char * Text,long unsigned length){
      size = length;
      if(CharByteArray)
        delete[] CharByteArray;
      CharByteArray = NewArr(Text);
      ToIntArray();
      try{
          ParseData();
      }
      catch(const char* exception){
         std::cout << exception;
          return nullptr;
      }
      return Result;
}
 
 
int decoder::ParseLength(int num){
    num &= 63;
    return num;
}
 
 
int decoder::pow(int num, int times){
    if(times == 0)
        return 1;
    if(times == 1)
        return num;
    if(times > 1)
        return num*pow(num,--times);
    return -1;
}
 
 
int decoder::CalculateBytes(int len){
    int calculated = 0,power = len*8-1;
    for(int i = 0;i < len && ++pArr;i++){
 
        if(*pArr == -1 )
            throw "CalculateBytes error";
 
        for(int q = 7;q >= 0;--q){
            if(CHECKBIT(*pArr,q)){
                calculated += pow(2,power);
            }
            --power;
        }
    }
    return calculated;
}
 
 
void decoder::CalculateIdentifierFirstByte(){ //there are only three types of first node 1,2,3 , first byte is calculated with (firstnode*40 + secondnode)
    if(*++pArr < 80){ //if first byte is less than 80 it means that first node is 1
 
        if(*pArr == -1 )
            throw "CalculateIndentifierFirstByte error";
 
        Result = Append(Result,(std::to_string(1) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-40)+ ".").c_str()); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else if (*pArr < 120) //means that first node is 2
    {
        Result = Append(Result,(std::to_string(2) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-80)+ ".").c_str()); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else // first node is 3
    {
        Result = Append(Result,(std::to_string(3) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-120)+ ".").c_str());
        return;
    }
}
 
 
int decoder::CalculateLongSID(int& size) {
  int length = 1, value = 0, SID = 0;
  for (;; ++pArr) {
    if (!CHECKBIT(*pArr, 7)) {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      break;
    }
    else
    {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      value = value << 8;
    }
  }
  for (int i = 0; i < length*8-1; ++i) {
    if(CHECKBIT(value,i)){
        SETBIT(SID,i-i/8);
    }
  }
  size += length-2;
  return SID;
 
}
 
 
void decoder::CalculateIdentifier(int len){
    CalculateIdentifierFirstByte();
    for(int i = 0; i<len && ++pArr ; ++i){
        if(*pArr == -1 || *(pArr+1) == -1)
            throw "CalculateIndentifier error";
        if(!CHECKBIT(*pArr,7)){ //if decimal number consists of only one byte
            Result = Append(Result,(std::to_string(*pArr) + ".").c_str());
        }else //if bit 7 is set it means that length of decimal number in bytes is bigger than one byte
        {
            Result = Append(Result,(std::to_string(CalculateLongSID(i)) + ".").c_str());
        }
    }
}
 
 
char * decoder::IntToHexChar(int number){
    char * hex = new char[3]{};
    char hexarr[] = "0123456789ABCDEF";
    int num = number/16;
    hex[0] = hexarr[num];
    num = number%16;
    hex[1] = hexarr[num];
    return hex;
}
 
 
void decoder::AppendOctetString(int length){
     for(int i = 0; i < length && ++pArr;++i){
         char * p = IntToHexChar(*pArr);
         Result = Append(Result,p);
         delete[] p;
     }
}
 
 
void decoder::OctetStringHandler(){
    if(!CHECKBIT(*++pArr,7)){
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result," Octet String : { ");
        AppendOctetString(ParseLength(*pArr));
        Result = Append(Result,"}");
    }
    ++pArr;
}
 
 
void decoder::ObjectIdentifierHandler(){
    Result = Append(Result," OBJECT INDENTIFIED WITH VALUE: { ");
    if(!CHECKBIT(*++pArr,7)){ //if length in one byte
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        CalculateIdentifier(*pArr-1);
    }
    else //behaviour not described
    {
        CalculateIdentifierFirstByte();
        CalculateIdentifier(ParseLength(*pArr));
    }
    ++pArr;
}
 
 
void decoder::IntegerHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result," INTEGER WITH VALUE: { ");
        Result = Append(Result, ((std::to_string(CalculateBytes(ParseLength(*pArr)))+ " }").c_str()));
    }
    else
    {
        Result = Append(Result," INTEGER WITH VALUE: { ");
        Result = Append(Result, (std::to_string(CalculateBytes(CalculateBytes(ParseLength(*pArr))))+ " }").c_str());
    }
    ++pArr;
}
 
 
void decoder::SequenceHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
            if(*pArr == -1 )
                throw "SequenceHandler error";
 
            Result = Append(Result," SEQUENCE WITH LENGTH: ");
            Result = Append(Result, (std::to_string(*pArr) + "{ \n\t").c_str());
      }
    else
    {
        Result = Append(Result," SEQUENCE WITH LENGTH: ");
        Result = Append(Result, (std::to_string(CalculateBytes(ParseLength(*pArr)))+ "\n\t").c_str());
    }
    ++pArr;
}
h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include "string.h"
 
 
#define SETBIT(number,bit) ((number) |= (pow(2,bit)))
#define CHECKBIT(number,bit) ((number) & (1 << (bit)))
 
class decoder{
    public:
        decoder();
 
        decoder(const decoder&);
 
        ~decoder();
 
        decoder& operator=(const decoder&);
 
        char * decode(const unsigned char * ,unsigned long);
 
    private:
        enum TYPES{
            ENDOFARRAY = -1,
            INTEGER = 0x02,
            OCTET_STRING = 0x04,
            OBJECT_IDENTIFIER = 0x06,
            SEQUENCE = 0x30
        };
        //Calculates number in power
        int pow(int,int);
 
        char* IntToHexChar(int);
 
        void AppendOctetString(int);
 
        int CalculateLongSID(int&);
 
        //Calculates all decimal values of indentifier
        void CalculateIdentifier(int);
 
        //Calculates first byte of indentifier which is decoded to two values
        void CalculateIdentifierFirstByte();
 
        //Convert byte array to decimal value
        int CalculateBytes(int);
 
        //Decoding encoded ans1.der string
        void ParseData();
 
        //Appends passed array with new array
        char * Append(char *,const char *);
 
        //Decodes length of front bytes
        int ParseLength(int);
 
        //Handles Octet String
        void OctetStringHandler();
 
        //Handles Object Indentifier
        void ObjectIdentifierHandler();
 
        //Handles Integer
        void IntegerHandler();
 
        //Handles Sequance
        void SequenceHandler();
 
        //Converts char array to int array
        void ToIntArray();
 
        //Copies value of passed array and returns new created one with same values
        const unsigned char *  NewArr(const unsigned char* );
 
        //Byte array as integers
        int * IntByteArray = nullptr;
 
        //Pointer to IntByteArray which is used to move through array
        int * pArr = nullptr;
 
        //Byte array as char
        const unsigned char * CharByteArray = nullptr;
 
        //The result decoded string
        char * Result = new char[1]{};
 
        //Size of IntByteArray
        unsigned long size = 0;
};
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
30.01.2020, 22:19
Цитата Сообщение от ReYalp Посмотреть сообщение
исправил что советовали и что смог
отсутствует include guard
это - фатальный косяк,
дальше в принципе код уже можно и не смотреть.
но я всё ж таки посмотрел первые 4ре строчки твоего хэдера.

C++
1
2
3
4
5
6
#include <iostream>
#include "string.h"
 
 
#define SETBIT(number,bit) ((number) |= (pow(2,bit)))
#define CHECKBIT(number,bit) ((number) & (1 << (bit)))
нафига это все нужно в хедере?
все эти заголовки и макросы - это детали реализации.
подключать их нужно к cpp, а не к хедеру.

не имей привычки прицеплять к хедеру всякий не нужный ему для работы хлам

важно понимать почему нельзя цеплять к хедеру всякий хлам.

во-первых, это нужно для инкапсуляции.
(почитай Макконелла, что это такое, и почему это так важно)

если вкратце: очень важно не отсвечивать деталями реализации.
чем меньше внешний мир знает об устройстве твоего класса - тем лучше.

если снаружи есть доступ к деталям реализации,
тогда снаружи кто нибудь может на них завязаться.
и тогда детали реализации уже нельзя будет изменить,
без риска сломать уже написанный код.

но если никто кроме твоего класса не знает о деталях его реализации,
тогда ты легко можешь его модифицировать без оглядки на остальную кодовую базу.


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


в-третьих, это оптимизирует время компиляции.
каждый сpp файл компилируется отдельно.
каждый раз заново к каждому такому cpp файлу прицепляется хедер,
который в свою очередь ещё что-то там прицепляет.
и потом весь этот хлам каждый раз заново компилируется-парсится.

вот будет у тебя проект из 10 cpp файлов.
и твой <iostream> будет 10 раз по новой компилироваться.
(в нём примерно 10'000 строк тяжелых шаблонов).

а если у тебя будет 100 cpp файлов?
а если 1'000 ?

а потом начинается нытьё, мол с++ медленно проекты компилирует.

это не с++ медленный.
это некоторые люди не думают головой, что и зачем они прицепляют.
можно же прицепить его к cpp файлу, где он используется.
и подключится только раз именно там,
где он действительно нужен.

C++
1
#include "string.h"
поподробнее о нём.

1.
я надеюсь тебе понятно, что в хэдере он нафиг не нужен.
его нужно перетащить в cpp

2.
почему системный путь #include "string.h" в кавычках?
системные пути должны быть в угловых скобках #include <string.h>
это нужно что бы:
- различать системные и пользовательские файлы
- оптимизация поиска нужного файла.
системный файл в системной папке будет обнаружен быстрее,
если сразу искать его в системной папке,
а не в путях пользователя.

2.
почему ты подключаешь сишную версию заголовка #include "string.h",
вместо того, что бы подключать правильную с++ версию #include <cstring>?
с++ версии могут иметь важные косметические дополнения.

ты же не хочешь наступить на грабли?


вот, я честно просмотрел целых 4ре строчки твоего кода.
исправишь деффекты, можно будет ещё посмотреть.
1
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
30.01.2020, 23:51  [ТС]
hoggy, никогда не использовал header guard ,спасибо за совет, вот исправил :
header
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#ifndef DECODER_H
#define DECODER_H
 class decoder{
    public:
        decoder();
 
        decoder(const decoder&);
 
        ~decoder();
 
        decoder& operator=(const decoder&);
 
        char * decode(const unsigned char * ,unsigned long);
 
    private:
        enum TYPES{
            ENDOFARRAY = -1,
            INTEGER = 0x02,
            OCTET_STRING = 0x04,
            OBJECT_IDENTIFIER = 0x06,
            SEQUENCE = 0x30
        };
        //Calculates number in power
        int pow(int,int);
 
        char* IntToHexChar(int);
 
        void AppendOctetString(int);
 
        int CalculateLongSID(int&);
 
        //Calculates all decimal values of indentifier
        void CalculateIdentifier(int);
 
        //Calculates first byte of indentifier which is decoded to two values
        void CalculateIdentifierFirstByte();
 
        //Convert byte array to decimal value
        int CalculateBytes(int);
 
        //Decoding encoded ans1.der string
        void ParseData();
 
        //Appends passed array with new array
        char * Append(char *,const char *);
 
        //Decodes length of front bytes
        int ParseLength(int);
 
        //Handles Octet String
        void OctetStringHandler();
 
        //Handles Object Indentifier
        void ObjectIdentifierHandler();
 
        //Handles Integer
        void IntegerHandler();
 
        //Handles Sequance
        void SequenceHandler();
 
        //Converts char array to int array
        void ToIntArray();
 
        //Copies value of passed array and returns new created one with same values
        const unsigned char *  NewArr(const unsigned char* );
 
        //Byte array as integers
        int * IntByteArray = nullptr;
 
        //Pointer to IntByteArray which is used to move through array
        int * pArr = nullptr;
 
        //Byte array as char
        const unsigned char * CharByteArray = nullptr;
 
        //The result decoded string
        char * Result = new char[1]{};
 
        //Size of IntByteArray
        unsigned long size = 0;
};
#endif

cpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#include "asn1der.h"
#include <iostream>
#include <cstring>
 
#define SETBIT(number,bit) ((number) |= (pow(2,bit)))
#define CHECKBIT(number,bit) ((number) & (1 << (bit)))
 
decoder::decoder(){
}
 
decoder::decoder(const decoder& obj){
    this->CharByteArray = obj.CharByteArray;
    this->IntByteArray = obj.IntByteArray;
    this->pArr = obj.IntByteArray;
    this->size = obj.size;
}
 
decoder::~decoder(){
    if(CharByteArray)
        delete[] CharByteArray;
    if(IntByteArray)
        delete[] IntByteArray;
}
 
decoder& decoder::operator=(const decoder& obj){
    this->CharByteArray = obj.CharByteArray;
    this->IntByteArray = obj.IntByteArray;
    this->pArr = obj.IntByteArray;
    this->size = obj.size;
    return *this;
}
 
char * decoder::Append(char * dst,const char * src){  
     unsigned long dstlen = strlen(dst),srclen =  strlen(src);
     char* temp = new char[dstlen+srclen+1];
     memcpy(temp, dst, dstlen);
     memcpy(temp + dstlen, src, srclen + 1);
     delete[] dst;
     return temp;
}
 
 
const unsigned char *  decoder::NewArr(const unsigned char* arr) {
    unsigned char * temp = new unsigned char[size+1]{};
    memcpy(temp,arr,size+1);
    return temp;
}
 
 
void decoder::ToIntArray(){
    IntByteArray = new int[size+1]{};
    for(unsigned int i = 0;i<size;++i){
        IntByteArray[i] = static_cast<unsigned int>(CharByteArray[i]);
    }
    IntByteArray[size] = -1;
    pArr = IntByteArray;
}
 
 
void decoder::ParseData(){
    switch (*pArr)
    {
        case ENDOFARRAY:
            break;
        case INTEGER:
            IntegerHandler();
            ParseData();
            break;
        case OCTET_STRING:
            OctetStringHandler();
            ParseData();
            break;
        case OBJECT_IDENTIFIER:
            ObjectIdentifierHandler();
            ParseData();
            Result = Append(Result,("}"));
            break;
        case SEQUENCE:
            SequenceHandler();
            ParseData();
            Result = Append(Result,("\n}"));
            break;
        default:
            break;
    }
}
 
 
char * decoder::decode(const unsigned char * Text,long unsigned length){
      size = length;
      if(CharByteArray)
        delete[] CharByteArray;
      CharByteArray = NewArr(Text);
      ToIntArray();
      try{
          ParseData();
      }
      catch(const char* exception){
         std::cout << exception;
          return nullptr;
      }
      return Result;
}
 
 
int decoder::ParseLength(int num){
    num &= 63;
    return num;
}
 
 
int decoder::pow(int num, int times){
    if(times == 0)
        return 1;
    if(times == 1)
        return num;
    if(times > 1)
        return num*pow(num,--times);
    return -1;
}
 
 
int decoder::CalculateBytes(int len){
    int calculated = 0,power = len*8-1;
    for(int i = 0;i < len && ++pArr;i++){
 
        if(*pArr == -1 )
            throw "CalculateBytes error";
 
        for(int q = 7;q >= 0;--q){
            if(CHECKBIT(*pArr,q)){
                calculated += pow(2,power);
            }
            --power;
        }
    }
    return calculated;
}
 
 
void decoder::CalculateIdentifierFirstByte(){ //there are only three types of first node 1,2,3 , first byte is calculated with (firstnode*40 + secondnode)
    if(*++pArr < 80){ //if first byte is less than 80 it means that first node is 1
 
        if(*pArr == -1 )
            throw "CalculateIndentifierFirstByte error";
 
        Result = Append(Result,(std::to_string(1) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-40)+ ".").c_str()); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else if (*pArr < 120) //means that first node is 2
    {
        Result = Append(Result,(std::to_string(2) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-80)+ ".").c_str()); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else // first node is 3
    {
        Result = Append(Result,(std::to_string(3) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-120)+ ".").c_str());
        return;
    }
}
 
 
int decoder::CalculateLongSID(int& size) {
  int length = 1, value = 0, SID = 0;
  for (;; ++pArr) {
    if (!CHECKBIT(*pArr, 7)) {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      break;
    }
    else
    {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      value = value << 8;
    }
  }
  for (int i = 0; i < length*8-1; ++i) {
    if(CHECKBIT(value,i)){
        SETBIT(SID,i-i/8);
    }
  }
  size += length-2;
  return SID;
 
}
 
 
void decoder::CalculateIdentifier(int len){
    CalculateIdentifierFirstByte();
    for(int i = 0; i<len && ++pArr ; ++i){
        if(*pArr == -1 || *(pArr+1) == -1)
            throw "CalculateIndentifier error";
        if(!CHECKBIT(*pArr,7)){ //if decimal number consists of only one byte
            Result = Append(Result,(std::to_string(*pArr) + ".").c_str());
        }else //if bit 7 is set it means that length of decimal number in bytes is bigger than one byte
        {
            Result = Append(Result,(std::to_string(CalculateLongSID(i)) + ".").c_str());
        }
    }
}
 
 
char * decoder::IntToHexChar(int number){
    char * hex = new char[3]{};
    char hexarr[] = "0123456789ABCDEF";
    int num = number/16;
    hex[0] = hexarr[num];
    num = number%16;
    hex[1] = hexarr[num];
    return hex;
}
 
 
void decoder::AppendOctetString(int length){
     for(int i = 0; i < length && ++pArr;++i){
         char * p = IntToHexChar(*pArr);
         Result = Append(Result,p);
         delete[] p;
     }
}
 
 
void decoder::OctetStringHandler(){
    if(!CHECKBIT(*++pArr,7)){
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result," Octet String : { ");
        AppendOctetString(ParseLength(*pArr));
        Result = Append(Result,"}");
    }
    ++pArr;
}
 
 
void decoder::ObjectIdentifierHandler(){
    Result = Append(Result," OBJECT INDENTIFIED WITH VALUE: { ");
    if(!CHECKBIT(*++pArr,7)){ //if length in one byte
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        CalculateIdentifier(*pArr-1);
    }
    else //behaviour not described
    {
        CalculateIdentifierFirstByte();
        CalculateIdentifier(ParseLength(*pArr));
    }
    ++pArr;
}
 
 
void decoder::IntegerHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result," INTEGER WITH VALUE: { ");
        Result = Append(Result, ((std::to_string(CalculateBytes(ParseLength(*pArr)))+ " }").c_str()));
    }
    else
    {
        Result = Append(Result," INTEGER WITH VALUE: { ");
        Result = Append(Result, (std::to_string(CalculateBytes(CalculateBytes(ParseLength(*pArr))))+ " }").c_str());
    }
    ++pArr;
}
 
 
void decoder::SequenceHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
            if(*pArr == -1 )
                throw "SequenceHandler error";
 
            Result = Append(Result," SEQUENCE WITH LENGTH: ");
            Result = Append(Result, (std::to_string(*pArr) + "{ \n\t").c_str());
      }
    else
    {
        Result = Append(Result," SEQUENCE WITH LENGTH: ");
        Result = Append(Result, (std::to_string(CalculateBytes(ParseLength(*pArr)))+ "\n\t").c_str());
    }
    ++pArr;
}


Добавлено через 41 минуту
вот исправил конструкторы
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#include "asn1der.h"
#include <iostream>
#include <cstring>
 
#define SETBIT(number,bit) ((number) |= (pow(2,bit)))
#define CHECKBIT(number,bit) ((number) & (1 << (bit)))
 
decoder::decoder(){
}
 
decoder::decoder(const decoder& obj){
    this->size = obj.size;
    unsigned char * NewChar = new unsigned char[this->size+1];
    memcpy(NewChar,obj.CharByteArray,size+1);
    CharByteArray = NewChar;
    memcpy(this->IntByteArray,obj.IntByteArray,size);
    this->pArr = this->IntByteArray;
}
 
 
decoder::decoder(decoder && obj){
    this->size = obj.size;
    this->IntByteArray = obj.IntByteArray;
    this->CharByteArray = obj.CharByteArray;
    this->pArr = obj.IntByteArray;
}
 
 
decoder::~decoder(){
    if(CharByteArray)
        delete[] CharByteArray;
    if(IntByteArray)
        delete[] IntByteArray;
}
 
 
decoder& decoder::operator=(decoder && obj){
    this->size = obj.size;
    this->IntByteArray = obj.IntByteArray;
    this->CharByteArray = obj.CharByteArray;
    this->pArr = obj.IntByteArray;
    return *this;
}
 
 
decoder& decoder::operator=(const decoder& obj){
    this->size = obj.size;
    unsigned char * NewChar = new unsigned char[this->size+1];
    memcpy(NewChar,obj.CharByteArray,size+1);
    CharByteArray = NewChar;
    memcpy(this->IntByteArray,obj.IntByteArray,size);
    this->pArr = this->IntByteArray;
    return *this;
}
 
char * decoder::Append(char * dst,const char * src){  
     unsigned long dstlen = strlen(dst),srclen =  strlen(src);
     char* temp = new char[dstlen+srclen+1];
     memcpy(temp, dst, dstlen);
     memcpy(temp + dstlen, src, srclen + 1);
     delete[] dst;
     return temp;
}
 
 
const unsigned char *  decoder::NewArr(const unsigned char* arr) {
    unsigned char * temp = new unsigned char[size+1]{};
    memcpy(temp,arr,size+1);
    return temp;
}
 
 
void decoder::ToIntArray(){
    IntByteArray = new int[size+1]{};
    for(unsigned int i = 0;i<size;++i){
        IntByteArray[i] = static_cast<unsigned int>(CharByteArray[i]);
    }
    IntByteArray[size] = -1;
    pArr = IntByteArray;
}
 
 
void decoder::ParseData(){
    switch (*pArr)
    {
        case ENDOFARRAY:
            break;
        case INTEGER:
            IntegerHandler();
            ParseData();
            break;
        case OCTET_STRING:
            OctetStringHandler();
            ParseData();
            break;
        case OBJECT_IDENTIFIER:
            ObjectIdentifierHandler();
            ParseData();
            Result = Append(Result,("}"));
            break;
        case SEQUENCE:
            SequenceHandler();
            ParseData();
            Result = Append(Result,("\n}"));
            break;
        default:
            break;
    }
}
 
 
char * decoder::decode(const unsigned char * Text,long unsigned length){
      size = length;
      if(CharByteArray)
        delete[] CharByteArray;
      CharByteArray = NewArr(Text);
      ToIntArray();
      try{
          ParseData();
      }
      catch(const char* exception){
         std::cout << exception;
          return nullptr;
      }
      return Result;
}
 
 
int decoder::ParseLength(int num){
    num &= 63;
    return num;
}
 
 
int decoder::pow(int num, int times){
    if(times == 0)
        return 1;
    if(times == 1)
        return num;
    if(times > 1)
        return num*pow(num,--times);
    return -1;
}
 
 
int decoder::CalculateBytes(int len){
    int calculated = 0,power = len*8-1;
    for(int i = 0;i < len && ++pArr;i++){
 
        if(*pArr == -1 )
            throw "CalculateBytes error";
 
        for(int q = 7;q >= 0;--q){
            if(CHECKBIT(*pArr,q)){
                calculated += pow(2,power);
            }
            --power;
        }
    }
    return calculated;
}
 
 
void decoder::CalculateIdentifierFirstByte(){ //there are only three types of first node 1,2,3 , first byte is calculated with (firstnode*40 + secondnode)
    if(*++pArr < 80){ //if first byte is less than 80 it means that first node is 1
 
        if(*pArr == -1 )
            throw "CalculateIndentifierFirstByte error";
 
        Result = Append(Result,(std::to_string(1) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-40)+ ".").c_str()); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else if (*pArr < 120) //means that first node is 2
    {
        Result = Append(Result,(std::to_string(2) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-80)+ ".").c_str()); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else // first node is 3
    {
        Result = Append(Result,(std::to_string(3) + ".").c_str());
        Result = Append(Result,(std::to_string(*pArr-120)+ ".").c_str());
        return;
    }
}
 
 
int decoder::CalculateLongSID(int& size) {
  int length = 1, value = 0, SID = 0;
  for (;; ++pArr) {
    if (!CHECKBIT(*pArr, 7)) {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      break;
    }
    else
    {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      value = value << 8;
    }
  }
  for (int i = 0; i < length*8-1; ++i) {
    if(CHECKBIT(value,i)){
        SETBIT(SID,i-i/8);
    }
  }
  size += length-2;
  return SID;
 
}
 
 
void decoder::CalculateIdentifier(int len){
    CalculateIdentifierFirstByte();
    for(int i = 0; i<len && ++pArr ; ++i){
        if(*pArr == -1 || *(pArr+1) == -1)
            throw "CalculateIndentifier error";
        if(!CHECKBIT(*pArr,7)){ //if decimal number consists of only one byte
            Result = Append(Result,(std::to_string(*pArr) + ".").c_str());
        }else //if bit 7 is set it means that length of decimal number in bytes is bigger than one byte
        {
            Result = Append(Result,(std::to_string(CalculateLongSID(i)) + ".").c_str());
        }
    }
}
 
 
char * decoder::IntToHexChar(int number){
    char * hex = new char[3]{};
    char hexarr[] = "0123456789ABCDEF";
    int num = number/16;
    hex[0] = hexarr[num];
    num = number%16;
    hex[1] = hexarr[num];
    return hex;
}
 
 
void decoder::AppendOctetString(int length){
     for(int i = 0; i < length && ++pArr;++i){
         char * p = IntToHexChar(*pArr);
         Result = Append(Result,p);
         delete[] p;
     }
}
 
 
void decoder::OctetStringHandler(){
    if(!CHECKBIT(*++pArr,7)){
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result," Octet String : { ");
        AppendOctetString(ParseLength(*pArr));
        Result = Append(Result,"}");
    }
    ++pArr;
}
 
 
void decoder::ObjectIdentifierHandler(){
    Result = Append(Result," OBJECT INDENTIFIED WITH VALUE: { ");
    if(!CHECKBIT(*++pArr,7)){ //if length in one byte
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        CalculateIdentifier(*pArr-1);
    }
    else //behaviour not described
    {
        CalculateIdentifierFirstByte();
        CalculateIdentifier(ParseLength(*pArr));
    }
    ++pArr;
}
 
 
void decoder::IntegerHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result," INTEGER WITH VALUE: { ");
        Result = Append(Result, ((std::to_string(CalculateBytes(ParseLength(*pArr)))+ " }").c_str()));
    }
    else
    {
        Result = Append(Result," INTEGER WITH VALUE: { ");
        Result = Append(Result, (std::to_string(CalculateBytes(CalculateBytes(ParseLength(*pArr))))+ " }").c_str());
    }
    ++pArr;
}
 
 
void decoder::SequenceHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
            if(*pArr == -1 )
                throw "SequenceHandler error";
 
            Result = Append(Result," SEQUENCE WITH LENGTH: ");
            Result = Append(Result, (std::to_string(*pArr) + "{ \n\t").c_str());
      }
    else
    {
        Result = Append(Result," SEQUENCE WITH LENGTH: ");
        Result = Append(Result, (std::to_string(CalculateBytes(ParseLength(*pArr)))+ "\n\t").c_str());
    }
    ++pArr;
}
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
31.01.2020, 00:27
Цитата Сообщение от hoggy Посмотреть сообщение
почитай Макконелла, что это такое, и почему это так важно
Вот, реально, навевает:
"Мы приглашаем тебя с нами целовать жопу МакКонелу Хэнку".

Не, книга - хорошая. Просто, все хорошее - хорошо в свое время. И ТС-у ее читать - явно рано. Просто, некоторые вещи постигаются только через боль и через практику. Иначе, прочитав хорошую книгу по кодингу, есть шанс в нее уверовать, как в истину в последней инстнации. Со всеми вытекающими.
Если хочешь, могу примеры, даже с этого форума, где, в общем-то, годную идею довели до маразма. Но, только в личку, обидятцо.
2
31.01.2020, 00:29

Не по теме:

Цитата Сообщение от avgoor Посмотреть сообщение
Просто, некоторые вещи постигаются только через боль и через практику. Иначе, прочитав хорошую книгу по кодингу, есть шанс в нее уверовать, как в истину в последней инстнации. Со всеми вытекающими.
Если хочешь, могу примеры, даже с этого форума, где, в общем-то, годную идею довели до маразма. Но, только в личку, обидятцо.
Интересненько )

0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
31.01.2020, 01:36  [ТС]
avgoor, а когда читать подобные книги не рано?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.01.2020, 01:36
Помогаю со студенческими работами здесь

оценка кода
Дайте оценку моему коду (https://onlinegdb.com/r1i-i8Cqm), укажите на ошибки

Оценка стиля кода
Народ, есть предложение. Оцените мой код. Не в смысле функционала - в смысле стиля написания. Значится, вот тут есть некий код: bool...

Оценка кода динамического двумерного массива
Доброго времени суток. Прошу оценить правильность выделения и удаления памяти, а также заполнения массива. Два примера. Вот первый. В...

Список учеников имеет следующую структуру: фамилия – класс - оценка по алгебре - оценка по физике - средний балл
Задание такое Список учеников имеет следующую структуру: фамилия – класс - оценка по алгебре - оценка по физике - средний балл. При...

Оценка стиля написания кода
Здравствуйте! Я к вам пожаловал не с очередной проблемой. Код у меня рабочий. Меня интересует то, насколько стандартен мой стиль...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru