TTKMusicPlayer  4.2.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
ttkcryptographichash.cpp
Go to the documentation of this file.
1 #include "ttkcryptographichash.h"
2 
3 #define XXTEA_MX (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z)
4 #define XXTEA_DELTA 0x9E3779B9
5 
6 namespace TTK
7 {
8  static const char *base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
9 
13  inline static bool isBase64(unsigned char c)
14  {
15  return isalnum(c) || (c == '+') || (c == '/');
16  }
17 }
18 
19 TTKString TTK::base64Encode(const unsigned char *bytes, unsigned int length)
20 {
21  TTKString ret;
22  int i = 0, j = 0;
23  unsigned char char_array_3[3], char_array_4[4];
24 
25  while(length--)
26  {
27  char_array_3[i++] = *(bytes++);
28  if(i == 3)
29  {
30  char_array_4[0] = (char_array_3[0] & 0xFC) >> 2;
31  char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xF0) >> 4);
32  char_array_4[2] = ((char_array_3[1] & 0x0F) << 2) + ((char_array_3[2] & 0xC0) >> 6);
33  char_array_4[3] = char_array_3[2] & 0x3F;
34 
35  for(i = 0; i < 4; ++i)
36  {
37  ret += base64_chars[char_array_4[i]];
38  }
39  i = 0;
40  }
41  }
42 
43  if(i)
44  {
45  for(j = i; j < 3; ++j)
46  {
47  char_array_3[j] = '\0';
48  }
49 
50  char_array_4[0] = (char_array_3[0] & 0xFC) >> 2;
51  char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xF0) >> 4);
52  char_array_4[2] = ((char_array_3[1] & 0x0F) << 2) + ((char_array_3[2] & 0xC0) >> 6);
53  char_array_4[3] = char_array_3[2] & 0x3F;
54 
55  for(j = 0; j < i + 1; ++j)
56  {
57  ret += base64_chars[char_array_4[j]];
58  }
59 
60  while((i++ < 3))
61  {
62  ret += '=';
63  }
64 
65  }
66  return ret;
67 }
68 
70 {
71  int length = bytes.length();
72  int i = 0, j = 0, in = 0;
73  unsigned char char_array_4[4], char_array_3[3];
74 
75  TTKString ret;
76  const TTKString container(base64_chars);
77 
78  while(length-- && (bytes[in] != '=') && isBase64(bytes[in]))
79  {
80  char_array_4[i++] = bytes[in]; in++;
81  if(i ==4)
82  {
83  for(i = 0; i < 4; ++i)
84  {
85  char_array_4[i] = container.find(char_array_4[i]);
86  }
87 
88  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
89  char_array_3[1] = ((char_array_4[1] & 0xF) << 4) + ((char_array_4[2] & 0x3C) >> 2);
90  char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
91 
92  for(i = 0; i < 3; ++i)
93  {
94  ret += char_array_3[i];
95  }
96  i = 0;
97  }
98  }
99 
100  if(i)
101  {
102  for(j = i; j < 4; ++j)
103  {
104  char_array_4[j] = 0;
105  }
106 
107  for(j = 0; j < 4; ++j)
108  {
109  char_array_4[j] = container.find(char_array_4[j]);
110  }
111 
112  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
113  char_array_3[1] = ((char_array_4[1] & 0xF) << 4) + ((char_array_4[2] & 0x3C) >> 2);
114  char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
115 
116  for(j = 0; j < i - 1; ++j)
117  {
118  ret += char_array_3[j];
119  }
120  }
121 
122  return ret;
123 }
124 
125 
126 QString TTKCryptographicHash::encrypt(const QString &data, const char *key)
127 {
128  const TTKString &result = xxteaEncrypt(data.toStdString(), key);
129  return QString::fromStdString(TTK::base64Encode((const unsigned char *)result.c_str(), result.length()));
130 }
131 
132 QString TTKCryptographicHash::decrypt(const QString &data, const char *key)
133 {
134  return QString::fromStdString(xxteaDecrypt(TTK::base64Decode(data.toStdString()), key));
135 }
136 
138 {
139  uchar dataCopy[1024];
140  strcpy((char*)dataCopy, (const char *)data.c_str());
141 
142  uchar keyCopy[1024];
143  strcpy((char*)keyCopy, key);
144 
145  xxtea_uint s[1];
146  uchar *encrypt = xxteaEncrypt(dataCopy, strlen((const char *)dataCopy), keyCopy, strlen((const char *)keyCopy), s);
147  const TTKString &encode = TTK::base64Encode(encrypt, s[0]);
148  free(encrypt);
149 
150  return encode;
151 }
152 
154 {
155  const TTKString &decode = TTK::base64Decode(data);
156  if(decode.empty())
157  {
158  return TTKString("");
159  }
160 
161  uchar dataCopy[1024];
162  memcpy(dataCopy, decode.c_str(), decode.length());
163 
164  dataCopy[decode.length()] = '\0';
165  uchar keyCopy[1024];
166  strcpy((char*)keyCopy, key);
167 
168  xxtea_uint s[1];
169  uchar *encrypt = xxteaDecrypt(dataCopy, decode.length(), keyCopy, strlen((const char *)keyCopy), s);
170  if(!encrypt)
171  {
172  return TTKString("false_false");
173  }
174 
175  TTKString raw = (char*)encrypt;
176  raw = QString::fromUtf8(raw.c_str()).toStdString();
177  free(encrypt);
178 
179  return raw;
180 }
181 
183 {
184  xxtea_uint n = len - 1;
185  xxtea_uint z = v[n], y = v[0], p, q = 6 + 52 / (n + 1), sum = 0, e;
186 
187  if(n < 1)
188  {
189  return;
190  }
191 
192  while(0 < q--)
193  {
194  sum += XXTEA_DELTA;
195  e = sum >> 2 & 3;
196  for(p = 0; p < n; ++p)
197  {
198  y = v[p + 1];
199  z = v[p] += XXTEA_MX;
200  }
201 
202  y = v[0];
203  z = v[n] += XXTEA_MX;
204  }
205 }
206 
208 {
209  xxtea_uint n = len - 1;
210  xxtea_uint z = v[n], y = v[0], p, q = 6 + 52 / (n + 1), sum = q * XXTEA_DELTA, e;
211 
212  if(n < 1)
213  {
214  return;
215  }
216 
217  while(sum != 0)
218  {
219  e = sum >> 2 & 3;
220  for(p = n; p > 0; --p)
221  {
222  z = v[p - 1];
223  y = v[p] -= XXTEA_MX;
224  }
225 
226  z = v[n];
227  y = v[0] -= XXTEA_MX;
228  sum -= XXTEA_DELTA;
229  }
230 }
231 
233 {
234  uchar *tmp = (uchar *)malloc(16);
235  memcpy(tmp, key, keyLength);
236  memset(tmp + keyLength, '\0', 16 - keyLength);
237  return tmp;
238 }
239 
240 xxtea_uint *TTKCryptographicHash::xxteaToUintArray(uchar *data, xxtea_uint len, int includeLength, xxtea_uint *retLength)
241 {
242  xxtea_uint i, n, *result;
243 
244  n = len >> 2;
245  n = (((len & 3) == 0) ? n : n + 1);
246 
247  if(includeLength)
248  {
249  result = (xxtea_uint *)malloc((n + 1) << 2);
250  result[n] = len;
251  *retLength = n + 1;
252  } else
253  {
254  result = (xxtea_uint *)malloc(n << 2);
255  *retLength = n;
256  }
257 
258  memset(result, 0, n << 2);
259  for(i = 0; i < len; ++i)
260  {
261  result[i >> 2] |= (xxtea_uint)data[i] << ((i & 3) << 3);
262  }
263 
264  return result;
265 }
266 
267 uchar *TTKCryptographicHash::xxteaToByteArray(xxtea_uint *data, xxtea_uint len, int includeLength, xxtea_uint *retLength)
268 {
269  xxtea_uint i, n, m;
270  uchar *result;
271 
272  n = len << 2;
273  if(includeLength)
274  {
275  m = data[len - 1];
276  if((m < n - 7) || (m > n - 4))
277  {
278  return nullptr;
279  }
280  n = m;
281  }
282 
283  result = (uchar *)malloc(n + 1);
284  for(i = 0; i < n; ++i)
285  {
286  result[i] = (uchar)((data[i >> 2] >> ((i & 3) << 3)) & 0xFF);
287  }
288 
289  result[n] = '\0';
290  *retLength = n;
291 
292  return result;
293 }
294 
295 uchar *TTKCryptographicHash::doXxteaEncrypt(uchar *data, xxtea_uint len, uchar *key, xxtea_uint *retLength)
296 {
297  uchar *result;
298  xxtea_uint *v, *k, vlen, klen;
299 
300  v = xxteaToUintArray(data, len, 1, &vlen);
301  k = xxteaToUintArray(key, 16, 0, &klen);
302 
303  xxteaUintEncrypt(v, vlen, k);
304  result = xxteaToByteArray(v, vlen, 0, retLength);
305 
306  free(v);
307  free(k);
308 
309  return result;
310 }
311 
312 uchar *TTKCryptographicHash::doXxteaDecrypt(uchar *data, xxtea_uint len, uchar *key, xxtea_uint *retLength)
313 {
314  uchar *result;
315  xxtea_uint *v, *k, vlen, klen;
316 
317  v = xxteaToUintArray(data, len, 0, &vlen);
318  k = xxteaToUintArray(key, 16, 0, &klen);
319 
320  xxteaUintDecrypt(v, vlen, k);
321  result = xxteaToByteArray(v, vlen, 1, retLength);
322 
323  free(v);
324  free(k);
325 
326  return result;
327 }
328 
329 uchar *TTKCryptographicHash::xxteaEncrypt(uchar *data, xxtea_uint dataLength, uchar *key, xxtea_uint keyLength, xxtea_uint *retLength)
330 {
331  uchar *result;
332  *retLength = 0;
333 
334  if(keyLength < 16)
335  {
336  uchar *key2 = fixKeyLength(key, keyLength);
337  result = doXxteaEncrypt(data, dataLength, key2, retLength);
338  free(key2);
339  }
340  else
341  {
342  result = doXxteaEncrypt(data, dataLength, key, retLength);
343  }
344 
345  return result;
346 }
347 
348 uchar *TTKCryptographicHash::xxteaDecrypt(uchar *data, xxtea_uint dataLength, uchar *key, xxtea_uint keyLength, xxtea_uint *retLength)
349 {
350  uchar *result;
351  *retLength = 0;
352 
353  if(keyLength < 16)
354  {
355  uchar *key2 = fixKeyLength(key, keyLength);
356  result = doXxteaDecrypt(data, dataLength, key2, retLength);
357  free(key2);
358  }
359  else
360  {
361  result = doXxteaDecrypt(data, dataLength, key, retLength);
362  }
363 
364  return result;
365 }
#define isalnum(__c__)
Definition: split.c:38
static const char * base64_chars
uint32_t xxtea_uint
static bool isBase64(unsigned char c)
TTKString xxteaEncrypt(const TTKString &data, const char *key)
uchar * doXxteaEncrypt(uchar *data, xxtea_uint len, uchar *key, xxtea_uint *retLength)
uchar * fixKeyLength(uchar *key, xxtea_uint keyLength)
uchar * xxteaToByteArray(xxtea_uint *data, xxtea_uint len, int includeLength, xxtea_uint *retLength)
std::string TTKString
Definition: ttkglobal.h:168
#define XXTEA_MX
#define XXTEA_DELTA
The namespace of the application object.
Definition: ttkcompat.h:24
static constexpr wchar_t key[]
uchar * doXxteaDecrypt(uchar *data, xxtea_uint len, uchar *key, xxtea_uint *retLength)
TTK_MODULE_EXPORT TTKString base64Decode(const TTKString &bytes)
QString decrypt(const QString &data, const char *key)
void xxteaUintDecrypt(xxtea_uint *v, xxtea_uint len, xxtea_uint *k)
TTK_MODULE_EXPORT TTKString base64Encode(const unsigned char *bytes, unsigned int len)
TTKString xxteaDecrypt(const TTKString &data, const char *key)
void free(voidpf ptr)
xxtea_uint * xxteaToUintArray(uchar *data, xxtea_uint len, int includeLength, xxtea_uint *retLength)
voidp malloc(uInt size)
QString encrypt(const QString &data, const char *key)
void xxteaUintEncrypt(xxtea_uint *v, xxtea_uint len, xxtea_uint *k)