C++:解析迅雷下载地址

一个简单的说明

其实看完这个文章你会发现实现这些真的很简单,假如你问我为什么前缀要用C++(已用多语言实现),我只能说:当你用C++去解析这些的时候,你会体验到“前所未有”的“快感(痛楚)”。

大多数语言都已经实现了的功能,在C++上却要自己动手去实现。不得不说,这或许是它到目前为止还受欢迎的原因之一吧。

原理

迅雷的下载地址是用base64实现加密的,所以,你尽可以去搜索:语言+base64(当然了,C/C++的实现会让你头晕)。

C++.
image-2157

C++实现

说明一下,时间仓促,这段代码来自网络。待日后研究透彻了,在来说原理吧。

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
#include<iostream>
using namespace std;

/**
 
  迅雷下载地址解码--因环境因素,未实际运行.

*/

static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
 
static inline bool is_base64(unsigned char c)  
{  
    return (isalnum(c) || (c == '+') || (c == '/'));  
}

std::string base64_decode(std::string const& encoded_string) {
    int in_len = encoded_string.size();
    int i = 0;
    int j = 0;
    int in_ = 0;
    unsigned char char_array_4[4], char_array_3[3];
    std::string ret;
    while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
        char_array_4[i++] = encoded_string[in_]; in_++;
        if (i ==4) {
            for (i = 0; i <4; i++)
                char_array_4[i] = base64_chars.find(char_array_4[i]);
            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
            for (i = 0; (i < 3); i++)
                ret += char_array_3[i];
            i = 0;
        }
    }
    if (i) {
        for (j = i; j <4; j++)
            char_array_4[j] = 0;
        for (j = 0; j <4; j++)
            char_array_4[j] = base64_chars.find(char_array_4[j]);
        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
        char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
        for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
    }
    return ret;
}

int main()
{
//未完善:请输入去掉[thunder://]之后的部分
string thunders;
cin >> thunders;
string base64url = base64_decode(thunders).replace(0,2,"");
cout << base64url << endl;
return 0;
}

python Logo
image-2158

python实现

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
#!/usr/bin/env python
# coding=utf-8

#-*-coding:utf-8-*-

'''

python-version:2.7.5

解析迅雷下载地址.

输入一个迅雷下载的地址,可以打印到控制台,也可以输出到文件.

1.现在默认打印到控制台.
2.输出到文件请取消 #1,#2,#3的注释,对齐代码并为#5添加注释.

'''

import os
import base64


__author__='puruidong'
__date__='2014.8.14'


print u"输入一个迅雷下载的地址:\n"
th=raw_input()
if(th.find("thunder://")!=-1):
    #1   fs=open("D:\/py\/test.txt","wb")
    th=th.replace("thunder://","")
    decodeurl=base64.b64decode(th)
    urls=decodeurl[2:len(decodeurl)]
    print u"\n\n转换结果:\n"+urls #5
    #2   fs.write(urls)
    #3   fs.close()
else:
    print u"\n\n错误提示:不是标准的迅雷下载地址!!"

java标志
image-2159

Java实现

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
import sun.misc.BASE64Decoder;
import java.util.Scanner;

/**
 * 迅雷下载地址转换.
 *
 *
 * Created by puruidong on 2014/8/13.
 */
public class Test {
    public static void main(String[] args)throws Exception {
        System.out.println("输入一个迅雷下载地址:");
        Scanner sc = new Scanner(System.in);
        String thunder = sc.next();
        if(thunder.indexOf("thunder://")!=-1) {
            thunder = thunder.replaceAll("thunder://", "");
            BASE64Decoder base = new BASE64Decoder();
            String urls = new String(base.decodeBuffer(thunder));
            urls = urls.substring(2, urls.length());
            System.out.println("转换结果:"+urls);
        }else
        {
            System.err.println("错误提示:不是标准的迅雷下载地址!");
        }
    }
}

其余未完善的部分,后面在研究吧。