@@ -100,30 +100,11 @@ private async Task<string> GetChallengeAsync()
100100 /// Get login data with username, password and "challenge".
101101 /// </summary>
102102 /// <returns>A dictionary contains the data.</returns>
103- /// <remarks>
104- /// This is a function translated from javascript.
105- /// <code language="JavaScript"><![CDATA[
106- /// jQuery.getJSON(url.replace("srun_portal", "get_challenge"), { "username": $data.username, "ip": $data.ip, "double_stack": "1" }, function(data) {
107- /// var token = "";
108- /// if (data.res != "ok") {
109- /// alert(data.error);
110- /// return;
111- /// }
112- /// token = data.challenge;
113- /// $data.info = "{SRBX1}" + base64.encode(jQuery.xEncode(JSON.stringify({ "username": $data.username, "password": $data.password, "ip": $data.ip, "acid": $data.ac_id, "enc_ver": enc}), token));
114- /// var hmd5 = new Hashes.MD5().hex_hmac(token, data.password);
115- /// $data.password = "{MD5}" + hmd5;
116- /// $data.chksum = new Hashes.SHA1().hex(token + $data.username + token + hmd5 + token + $data.ac_id + token + $data.ip + token + n + token + type + token + $data.info);
117- /// $data.n = n;
118- /// $data.type = type;
119- /// return get(url, $data, callback, "jsonp");
120- /// });
121- /// ]]></code>
122- /// </remarks>
123103 private async Task < Dictionary < string , string > > GetLoginDataAsync ( )
124104 {
125- const string passwordMD5 = "5e543256c480ac577d30f76f9120eb74" ;
105+ // const string passwordMD5 = "5e543256c480ac577d30f76f9120eb74";
126106 string token = await GetChallengeAsync ( ) ;
107+ string passwordMD5 = CryptographyHelper . GetHMACMD5 ( token ) ;
127108 if ( loginDataDictionary == null )
128109 {
129110 loginDataDictionary = new Dictionary < string , string >
@@ -136,267 +117,11 @@ private async Task<Dictionary<string, string>> GetLoginDataAsync()
136117 [ "password" ] = "{MD5}" + passwordMD5
137118 } ;
138119 }
139- loginDataDictionary [ "info" ] = "{SRBX1}" + Base64Encode ( XEncode ( string . Format ( LoginInfoJson , Username , Password ) , token ) ) ;
120+ loginDataDictionary [ "info" ] = "{SRBX1}" + CryptographyHelper . Base64Encode ( CryptographyHelper . XEncode ( string . Format ( LoginInfoJson , Username , Password ) , token ) ) ;
140121 loginDataDictionary [ "username" ] = Username ;
141122 loginDataDictionary [ "chksum" ] = CryptographyHelper . GetSHA1 ( string . Format ( ChkSumData , token , Username , passwordMD5 , loginDataDictionary [ "info" ] ) ) ;
142123 return loginDataDictionary ;
143124 }
144- #region Encode methods
145- /// <summary>
146- /// Encode a <see cref="string"/> to its UTF-8 form.
147- /// </summary>
148- /// <param name="a">String to be encoded.</param>
149- /// <param name="b">Whether to add the length of the string in the end.</param>
150- /// <returns>A <see cref="uint"/> array contains encoded string.</returns>
151- /// <remarks>
152- /// This is a function translated from javascript.
153- /// <code language="JavaScript"><![CDATA[
154- /// function s(a, b) {
155- /// var c = a.length,
156- /// v = [];
157- /// for (var i = 0; i < c; i += 4) {
158- /// v[i >> 2] = a.charCodeAt(i) | a.charCodeAt(i + 1) << 8 | a.charCodeAt(i + 2) << 16 | a.charCodeAt(i + 3) << 24;
159- /// }
160- /// if (b) {
161- /// v[v.length] = c;
162- /// }
163- /// return v;
164- /// }
165- /// ]]></code>
166- /// </remarks>
167- private static unsafe uint [ ] S ( string a , bool b )
168- {
169- int c = a . Length ;
170- int n = c / 4 ;
171- n += c % 4 != 0 ? 1 : 0 ;
172- //Array is 30 times faster than stack array and Encoding.GetBytes().
173- uint [ ] v ;
174- if ( b )
175- {
176- v = new uint [ n + 1 ] ;
177- v [ n ] = ( uint ) c ;
178- }
179- else
180- {
181- v = new uint [ n >= 4 ? n : 4 ] ;
182- }
183- fixed ( uint * pv = v )
184- {
185- byte * pb = ( byte * ) pv ;
186- for ( int i = 0 ; i < c ; i ++ )
187- {
188- pb [ i ] = ( byte ) a [ i ] ;
189- }
190- }
191- return v ;
192- }
193- /// <summary>
194- /// Decode a <see cref="string"/> from its UTF-8 form.
195- /// </summary>
196- /// <param name="a">A <see cref="uint"/> array contains the encoded string.</param>
197- /// <param name="b">Whether the length of the original string is in the end.</param>
198- /// <returns>Decoded string.</returns>
199- /// <remarks>
200- /// This is a function translated from javascript.
201- /// <code language="JavaScript"><![CDATA[
202- /// function l(a, b) {
203- /// var d = a.length,
204- /// c = (d - 1) << 2;
205- /// if (b) {
206- /// var m = a[d - 1];
207- /// if ((m<c - 3) || (m > c))
208- /// return null;
209- /// c = m;
210- /// }
211- /// for (var i = 0; i < d; i++) {
212- /// a[i] = String.fromCharCode(a[i] & 0xff, a[i] >>> 8 & 0xff, a[i] >>> 16 & 0xff, a[i] >>> 24 & 0xff);
213- /// }
214- /// if (b) {
215- /// return a.join('').substring(0, c);
216- /// } else {
217- /// return a.join('');
218- /// }
219- /// }
220- /// ]]></code>
221- /// </remarks>
222- private static unsafe string L ( uint [ ] a , bool b )
223- {
224- int d = a . Length ;
225- uint c = ( ( uint ) ( d - 1 ) ) << 2 ;
226- if ( b )
227- {
228- uint m = a [ d - 1 ] ;
229- if ( m < c - 3 || m > c )
230- {
231- return null ;
232- }
233- c = m ;
234- }
235- fixed ( uint * pa = a )
236- {
237- byte * pb = ( byte * ) pa ;
238- int n = d << 2 ;
239- //When the return string needs subtracted, stack array is a little faster than array;
240- //otherwise, array is 1.2 times faster than stack array.
241- char [ ] aa = new char [ n ] ;
242- for ( int i = 0 ; i < n ; i ++ )
243- {
244- aa [ i ] = ( char ) pb [ i ] ;
245- }
246- if ( b )
247- {
248- return new string ( aa , 0 , ( int ) c ) ;
249- }
250- else
251- {
252- return new string ( aa ) ;
253- }
254- }
255- }
256- /// <summary>
257- /// Encode a string by a special TEA algorithm.
258- /// </summary>
259- /// <param name="str">String to be encoded.</param>
260- /// <param name="key">Key to encode.</param>
261- /// <returns>Encoded string.</returns>
262- /// <remarks>
263- /// This is a function translated from javascript.
264- /// <code language="JavaScript"><![CDATA[
265- /// xEncode: function(str, key) {
266- /// if (str == "") {
267- /// return "";
268- /// }
269- /// var v = s(str, true),
270- /// k = s(key, false);
271- /// if (k.length < 4) {
272- /// k.length = 4;
273- /// }
274- /// var n = v.length - 1,
275- /// z = v[n],
276- /// y = v[0],
277- /// c = 0x86014019 | 0x183639A0,
278- /// m,
279- /// e,
280- /// p,
281- /// q = Math.floor(6 + 52 / (n + 1)),
282- /// d = 0;
283- /// while (0 < q--) {
284- /// d = d + c & (0x8CE0D9BF | 0x731F2640);
285- /// e = d >>> 2 & 3;
286- /// for (p = 0; p<n; p++) {
287- /// y = v[p + 1];
288- /// m = z >>> 5 ^ y << 2;
289- /// m += (y >>> 3 ^ z << 4) ^ (d ^ y);
290- /// m += k[(p & 3) ^ e] ^ z;
291- /// z = v[p] = v[p] + m & (0xEFB8D130 | 0x10472ECF);
292- /// }
293- /// y = v[0];
294- /// m = z >>> 5 ^ y << 2;
295- /// m += (y >>> 3 ^ z << 4) ^ (d ^ y);
296- /// m += k[(p & 3) ^ e] ^ z;
297- /// z = v[n] = v[n] + m & (0xBB390742 | 0x44C6F8BD);
298- /// }
299- /// return l(v, false);
300- /// }
301- /// ]]></code>
302- /// </remarks>
303- private static string XEncode ( string str , string key )
304- {
305- if ( str . Length == 0 )
306- {
307- return string . Empty ;
308- }
309- uint [ ] v = S ( str , true ) ;
310- uint [ ] k = S ( key , false ) ;
311- int n = v . Length - 1 ;
312- uint z = v [ n ] ;
313- uint y = v [ 0 ] ;
314- int q = 6 + 52 / ( n + 1 ) ;
315- uint d = 0 ;
316- while ( q -- > 0 )
317- {
318- d += 0x9E3779B9 ;
319- uint e = ( d >> 2 ) & 3 ;
320- for ( int p = 0 ; p <= n ; p ++ )
321- {
322- y = v [ p == n ? 0 : p + 1 ] ;
323- uint m = ( z >> 5 ) ^ ( y << 2 ) ;
324- m += ( y >> 3 ) ^ ( z << 4 ) ^ ( d ^ y ) ;
325- m += k [ ( p & 3 ) ^ ( int ) e ] ^ z ;
326- z = v [ p ] += m ;
327- }
328- }
329- return L ( v , false ) ;
330- }
331-
332- private static readonly string Base64N = "LVoJPiCN2R8G90yg+hmFHuacZ1OWMnrsSTXkYpUq/3dlbfKwv6xztjI7DeBE45QA" ;
333- /// <summary>
334- /// Encode a string to base64 in a special way.
335- /// </summary>
336- /// <param name="t">String to be encoded.</param>
337- /// <returns>Encoded string.</returns>
338- /// <remarks>
339- /// This is a function translated from javascript.
340- /// <code language="JavaScript"><![CDATA[
341- /// Base64: function() {
342- /// var n = "LVoJPiCN2R8G90yg+hmFHuacZ1OWMnrsSTXkYpUq/3dlbfKwv6xztjI7DeBE45QA",
343- /// r = "=",
344- /// o = false,
345- /// f = false;
346- /// this.encode = function(t) {
347- /// var o,
348- /// i,
349- /// h,
350- /// u = "",
351- /// a = t.length;
352- /// r = r || "=";
353- /// t = f ? e(t) : t;
354- /// for (o = 0; o < a; o += 3) {
355- /// h = t.charCodeAt(o) << 16 | (o + 1 < a ? t.charCodeAt(o+1) << 8 : 0) | (o + 2 < a ? t.charCodeAt(o+2) : 0);
356- /// for ( i = 0; i < 4; i += 1) {
357- /// if (o * 8 + i * 6 > a * 8) {
358- /// u += r
359- /// } else {
360- /// u += n.charAt(h >>> 6 * (3 - i) & 63)
361- /// }
362- /// }
363- /// }
364- /// return u
365- /// };
366- /// }
367- /// ]]></code>
368- /// </remarks>
369- private unsafe static string Base64Encode ( string t )
370- {
371- int a = t . Length ;
372- int len = a / 3 * 4 ;
373- len += a % 3 != 0 ? 4 : 0 ;
374- //Stack array is 30 times faster than array, StringBuilder and Converter.ToBase64String().
375- char * u = stackalloc char [ len ] ;
376- char r = '=' ;
377- int h = 0 ;
378- byte * p = ( byte * ) & h ;
379- int ui = 0 ;
380- for ( int o = 0 ; o < a ; o += 3 )
381- {
382- p [ 2 ] = ( byte ) t [ o ] ;
383- p [ 1 ] = ( byte ) ( o + 1 < a ? t [ o + 1 ] : 0 ) ;
384- p [ 0 ] = ( byte ) ( o + 2 < a ? t [ o + 2 ] : 0 ) ;
385- for ( int i = 0 ; i < 4 ; i += 1 )
386- {
387- if ( o * 8 + i * 6 > a * 8 )
388- {
389- u [ ui ++ ] = r ;
390- }
391- else
392- {
393- u [ ui ++ ] = Base64N [ h >> 6 * ( 3 - i ) & 0x3F ] ;
394- }
395- }
396- }
397- return new string ( u , 0 , len ) ;
398- }
399- #endregion
400125 }
401126 /// <summary>
402127 /// Exposes methods to login, logout and get flux from https://auth4.tsinghua.edu.cn/.
0 commit comments