-
Notifications
You must be signed in to change notification settings - Fork 0
/
Converter.cpp
194 lines (150 loc) · 3.74 KB
/
Converter.cpp
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
#include "include/Converter.h"
#include "include/IO.h"
#include "include/Utils.h"
char Converter::intToDigit(int value)
{
char digit;
digit = '0' + value;
return digit;
}
int Converter::digitToInt(char digit)
{
int value;
value = digit - '0';
return value;
}
byte Converter::stringToByte(string str)
{
byte res = 0;
for (char bit : str)
{
//? Dịch trái sang một vị trí để có vị trí trống ở cuối
res = res << 1;
//? Thêm bit vào cuối
res += digitToInt(bit);
}
return res;
}
string Converter::byteToString(byte n, bool isReversed)
{
string res;
for (int i = 0; i < 8; i++)
{
//? Lấy bit thứ i
res += intToDigit(n & 1);
//? Dịch dãy các bits sang một bit để lấy bit tiếp theo
n >>= 1;
}
if (isReversed) res = reverseString(res);
return res;
}
BigInt Converter::binaryStrToBigInt(string binStr)
{
int length = binStr.length();
int offset = length;
int byteCount = length / 8 + (length % 8 != 0);
BigInt res;
res.byteCount = byteCount;
res.bytes = (byte*)malloc(res.byteCount * sizeof(byte));
//? Tách các octets
for (int i = 0; i < res.byteCount; i++)
{
string byteStr;
//? Tách các byte từ phải qua
if (length - 8 >= 0)
byteStr = binStr.substr(offset - 8, 8);
else
byteStr = binStr.substr(0, length);
res.bytes[i] = stringToByte(byteStr);
offset -= 8;
length -= 8;
}
return res;
}
string Converter::bigIntToBinaryStr(BigInt n)
{
string res;
for (int i = n.byteCount - 1; i >= 0; i--)
{
string str = byteToString(n.bytes[i], true);
res += str;
}
return res;
}
string Converter::bigIntToDecimalStr(BigInt n)
{
bool sign = n.isNegative();
string res;
BigInt i = abs(n), base = 10, r;
//? Tương tự như phép chuyển số thập phân sang chuỗi của kiểu int:
do {
//? Lấy i chia cho cơ số là 10
division(i, base, i, r);
//? Đảm bảo kết quả của phép chia luôn dương
i = abs(i);
//? Lấy giá trị của số dư (max = 9)
int value = r.getIntValue();
//? Chuyển thành dạng chữ số
char digit = intToDigit(value);
//? Cộng vào phía trước chuỗi
res = digit + res;
} while (i > 0);
if (sign == true) {
res = "-" + res;
}
return res;
}
//! Warn: khi kích thước BigInt::maxByteCount không đủ có thể dẫn đến tràn số
BigInt Converter::decimalStrToBigInt(string decStr)
{
BigInt res = 0;
int length = decStr.length();
if (length == 0) return res;
BigInt d = 0;
BigInt i = 1;
BigInt base = 10;
//? Tương tự như phép chuyển chuỗi sang số thập phân của kiểu int:
//? lặp qua từng chữ số d ở vị trí j (j giảm dần)
//? và cộng res cho d * i (i = 10^(length - 1 - j)).
for (int j = length - 1; j > 0; j--)
{
d = digitToInt(decStr[j]);
res = res + d * i;
i = i * base;
}
//? Nếu ký tự đầu là dấu trừ thì lấy bù 2
if (decStr[0] == '-')
{
res = twoComplement(res);
}
//? ngược lại thì res = res + d * i
else
{
d = digitToInt(decStr[0]);
res = res + d * i;
}
// Todo: cân nhắc việc cắt bớt byte
//? Bỏ bớt các byte thừa
//removeTrailingBytesIfNull(res);
//? Làm tròn số byte cho thành có dạng 2^k
//roundByteCount(res);
return res;
}
tuple<BigInt, BigInt, BigInt> Converter::toRSAKeys(tuple<string, string, string> keysStr, int base)
{
auto& [nStr, eStr, dStr] = keysStr;
BigInt n, e, d;
if (base == BigIntBase::BASE_10)
{
n = converter.decimalStrToBigInt(nStr);
e = converter.decimalStrToBigInt(eStr);
d = converter.decimalStrToBigInt(dStr);
}
else if (base == BigIntBase::BASE_2)
{
n = converter.binaryStrToBigInt(nStr);
e = converter.binaryStrToBigInt(eStr);
d = converter.binaryStrToBigInt(dStr);
}
return std::make_tuple(n, e, d);
}