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