TTKMusicPlayer  4.1.3.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 
136 QString TTKCryptographicHash::encrypt(const QString &data, const char *key)
137 {
138  const TTKString &result = xxteaEncrypt(data.toStdString(), key);
139  return QString::fromStdString(TTK::base64Encode((const unsigned char *)result.c_str(), result.length()));
140 }
141 
142 QString TTKCryptographicHash::decrypt(const QString &data, const char *key)
143 {
144  return QString::fromStdString(xxteaDecrypt(TTK::base64Decode(data.toStdString()), key));
145 }
146 
148 {
149  uchar dataCopy[1024];
150  strcpy((char*)dataCopy, (const char *)data.c_str());
151 
152  uchar keyCopy[1024];
153  strcpy((char*)keyCopy, key);
154 
155  xxtea_uint s[1];
156  uchar *encrypt = xxteaEncrypt(dataCopy, strlen((const char *)dataCopy), keyCopy, strlen((const char *)keyCopy), s);
157  const TTKString &encode = TTK::base64Encode(encrypt, s[0]);
158  free(encrypt);
159 
160  return encode;
161 }
162 
164 {
165  const TTKString &decode = TTK::base64Decode(data);
166  if(decode.empty())
167  {
168  return TTKString("");
169  }
170 
171  uchar dataCopy[1024];
172  memcpy(dataCopy, decode.c_str(), decode.length());
173 
174  dataCopy[decode.length()] = '\0';
175  uchar keyCopy[1024];
176  strcpy((char*)keyCopy, key);
177 
178  xxtea_uint s[1];
179  uchar *encrypt = xxteaDecrypt(dataCopy, decode.length(), keyCopy, strlen((const char *)keyCopy), s);
180  if(!encrypt)
181  {
182  return TTKString("false_false");
183  }
184 
185  TTKString raw = (char*)encrypt;
186  raw = QString::fromUtf8(raw.c_str()).toStdString();
187  free(encrypt);
188 
189  return raw;
190 }
191 
193 {
194  xxtea_uint n = len - 1;
195  xxtea_uint z = v[n], y = v[0], p, q = 6 + 52 / (n + 1), sum = 0, e;
196 
197  if(n < 1)
198  {
199  return;
200  }
201 
202  while(0 < q--)
203  {
204  sum += XXTEA_DELTA;
205  e = sum >> 2 & 3;
206  for(p = 0; p < n; ++p)
207  {
208  y = v[p + 1];
209  z = v[p] += XXTEA_MX;
210  }
211 
212  y = v[0];
213  z = v[n] += XXTEA_MX;
214  }
215 }
216 
218 {
219  xxtea_uint n = len - 1;
220  xxtea_uint z = v[n], y = v[0], p, q = 6 + 52 / (n + 1), sum = q * XXTEA_DELTA, e;
221 
222  if(n < 1)
223  {
224  return;
225  }
226 
227  while(sum != 0)
228  {
229  e = sum >> 2 & 3;
230  for(p = n; p > 0; --p)
231  {
232  z = v[p - 1];
233  y = v[p] -= XXTEA_MX;
234  }
235 
236  z = v[n];
237  y = v[0] -= XXTEA_MX;
238  sum -= XXTEA_DELTA;
239  }
240 }
241 
243 {
244  uchar *tmp = (uchar *)malloc(16);
245  memcpy(tmp, key, keyLength);
246  memset(tmp + keyLength, '\0', 16 - keyLength);
247  return tmp;
248 }
249 
250 xxtea_uint *TTKCryptographicHash::xxteaToUintArray(uchar *data, xxtea_uint len, int includeLength, xxtea_uint *retLength)
251 {
252  xxtea_uint i, n, *result;
253 
254  n = len >> 2;
255  n = (((len & 3) == 0) ? n : n + 1);
256 
257  if(includeLength)
258  {
259  result = (xxtea_uint *)malloc((n + 1) << 2);
260  result[n] = len;
261  *retLength = n + 1;
262  } else
263  {
264  result = (xxtea_uint *)malloc(n << 2);
265  *retLength = n;
266  }
267 
268  memset(result, 0, n << 2);
269  for(i = 0; i < len; ++i)
270  {
271  result[i >> 2] |= (xxtea_uint)data[i] << ((i & 3) << 3);
272  }
273 
274  return result;
275 }
276 
277 uchar *TTKCryptographicHash::xxteaToByteArray(xxtea_uint *data, xxtea_uint len, int includeLength, xxtea_uint *retLength)
278 {
279  xxtea_uint i, n, m;
280  uchar *result;
281 
282  n = len << 2;
283  if(includeLength)
284  {
285  m = data[len - 1];
286  if((m < n - 7) || (m > n - 4))
287  {
288  return nullptr;
289  }
290  n = m;
291  }
292 
293  result = (uchar *)malloc(n + 1);
294  for(i = 0; i < n; ++i)
295  {
296  result[i] = (uchar)((data[i >> 2] >> ((i & 3) << 3)) & 0xFF);
297  }
298 
299  result[n] = '\0';
300  *retLength = n;
301 
302  return result;
303 }
304 
305 uchar *TTKCryptographicHash::doXxteaEncrypt(uchar *data, xxtea_uint len, uchar *key, xxtea_uint *retLength)
306 {
307  uchar *result;
308  xxtea_uint *v, *k, vlen, klen;
309 
310  v = xxteaToUintArray(data, len, 1, &vlen);
311  k = xxteaToUintArray(key, 16, 0, &klen);
312 
313  xxteaUintEncrypt(v, vlen, k);
314  result = xxteaToByteArray(v, vlen, 0, retLength);
315 
316  free(v);
317  free(k);
318 
319  return result;
320 }
321 
322 uchar *TTKCryptographicHash::doXxteaDecrypt(uchar *data, xxtea_uint len, uchar *key, xxtea_uint *retLength)
323 {
324  uchar *result;
325  xxtea_uint *v, *k, vlen, klen;
326 
327  v = xxteaToUintArray(data, len, 0, &vlen);
328  k = xxteaToUintArray(key, 16, 0, &klen);
329 
330  xxteaUintDecrypt(v, vlen, k);
331  result = xxteaToByteArray(v, vlen, 1, retLength);
332 
333  free(v);
334  free(k);
335 
336  return result;
337 }
338 
339 uchar *TTKCryptographicHash::xxteaEncrypt(uchar *data, xxtea_uint dataLength, uchar *key, xxtea_uint keyLength, xxtea_uint *retLength)
340 {
341  uchar *result;
342  *retLength = 0;
343 
344  if(keyLength < 16)
345  {
346  uchar *key2 = fixKeyLength(key, keyLength);
347  result = doXxteaEncrypt(data, dataLength, key2, retLength);
348  free(key2);
349  }
350  else
351  {
352  result = doXxteaEncrypt(data, dataLength, key, retLength);
353  }
354 
355  return result;
356 }
357 
358 uchar *TTKCryptographicHash::xxteaDecrypt(uchar *data, xxtea_uint dataLength, uchar *key, xxtea_uint keyLength, xxtea_uint *retLength)
359 {
360  uchar *result;
361  *retLength = 0;
362 
363  if(keyLength < 16)
364  {
365  uchar *key2 = fixKeyLength(key, keyLength);
366  result = doXxteaDecrypt(data, dataLength, key2, retLength);
367  free(key2);
368  }
369  else
370  {
371  result = doXxteaDecrypt(data, dataLength, key, retLength);
372  }
373 
374  return result;
375 }
#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 char *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 char *key)
void xxteaUintDecrypt(xxtea_uint *v, xxtea_uint len, xxtea_uint *k)
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)