探讨短网址生成原理
关于短网址:短网址算法:
其实短网址的算法跟我们倒没啥关系,因为没有服务器搭建算出来也没用,而且最重要的是这种签名拉~校验拉~算法拉~Hash拉~数学拉什么的。。。正常人是绝对不会感兴趣的。。。。。简而言之,就是通过MD5算法生成签名,然后划分为4段,再进行位运算,再进行字母表索引得到特定字符,最后会生成4个6位字符串,取其中任意一个作为当前短网址。至于重复的问题,首先这个算法算出来以后重复概率应该不高?(咳咳,其实我也不知道高不高,不过每位有26+26+10应该是重复概率很低咯),如果遇到重复的就取另外的字符串嘛,反正先到先得,先映射了的就不用管了。 短网址接口:
对于开发者来说,只需要调用接口获得短网址服务器返回的信息就足够了。目前国内的很多门户网站基本都开通了短网址的服务。
腾讯: url.cn
网易:126.am
新浪: t.cn
人人:rrurl.cn
百度:dwz.cn
第一家提供短网址服务的公司: tinyurl.cn
一般短网址接口的使用方法都是POST参数到服务器,然后服务器返回信息。不过找了下貌似很多都没有开放接口,有的网站开放了接口但是参数里必须要求有用户登陆啊,用户授权神马的。所以还是萌萌的度娘好,完全免费调用,参数干净明朗。而且度娘之前就搞过短网址服务不过由于域名实在太长,被称为网址最长的短网址服务。所以后来悄悄收购了dwz.cn的域名重新低调上线,真是难为度娘了。度娘不哭~~站起来X。
1、生成短网址
请求:向dwz.cn/create.php发送post请求,发送数据包括url=长网址
返回:json格式的数据
1、status!=0 出错,查看err_msg获得错误信息(UTF-8编码)
2、成功,返回生成的短网址 tinyurl字段 2、自定义短网址
请求:向dwz.cn/create.php发送post请求,发送数据包括url=长网址&alias=自定义网址
返回:json格式的数据
1、Status!=0 出错,查看err_msg获得错误信息(UTF-8编码)
2、成功,返回生成的短网址 tinyurl字段 HTTP请求:
一般短网址接口的使用方法都是POST参数到服务器,然后服务器返回信息。不过找了下貌似很多都没有开放接口,有的网站开放了接口请求参数要求用户的授权或登陆。客户端(可以是浏览器,其他应用程序)与服务器进行交互,必须要发送请求,这里用的是HTTP协议。常用的一般是GET请求和POST请求,简单来说两种请求方式基本相同,都是提交数据到服务器。区别在于GET方法是通过URL来提交数据,服务器从收到的URL里解析数据,这样做从安全角度来讲要低一些,而且不能提交大量的数据。POST方法是通过加密的表单方式传送,所以数据量可以比较大且安全。像QQ空间,人人的访问应该就是发送的GET请求,从URL栏就可以直观看到相应的参数如帐号,当前目录是相册还是日志等等,而密码注册一类的都是POST请求。
就实际代码来看,java的请求比较简单,一些脚本语言也应该比较简单。java里使用封装好的URL,URLCONNECTION可以轻松请求到数据。而VC就特别的麻烦(而且类种类繁多,参数繁多,步骤繁多,总而言之也是个天坑!)。
1、通过CInternetSession建立会话
2、准备好各参数,数据报头部,里面包含协议方式,接收编码,请求方式等等
3、通过CHttpConnection建立连接
4、通过CHttpFile建立读写文件pfile
5、 使用pfile来OpenRequest,SendRequest
6、读取返回数据,关闭连接
VC是天坑。。。。。还可以用其他API,WINHTTP包,TCP/IP。。。。不过每种都很复杂麻烦而且搅在一堆 JAVA 在网络方面确实很方便:
view plaincopy
/*****************************
* 逸雨清风出品
* CSDN:http://blog.csdn.net/xyydyyqf
* DATE: 2013-6-1
* 祝我儿童节快乐!
******************************/
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.security.acl.Owner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class dwz extends JFrame implements ActionListener
{
private static char[] shortdwz = new char;
private static char[] line2;
private static String line;
private static char[] suitable;
private JPanel panel;
private JButton btncreat,btnclear,btncopy;
private JLabel lbllong,lblshort,lblcopy,lblmyshort,lblhelp;
private JTextField txtlong;
private JTextField txtshort;
private JTextField txtmyshort;
public dwz()
{
super("短网址生成器");
panel = new JPanel();
lbllong = new JLabel("原网址");
lblshort = new JLabel(" 短网址");
lblcopy = new JLabel("等待复制");
lblmyshort = new JLabel("自定义 http://dwz.cn/");
lblhelp = new JLabel("字母,数字,破折号");
txtlong = new JTextField(30);
txtshort = new JTextField(22);
txtmyshort = new JTextField(14);txtmyshort.setText("");
txtlong.setHorizontalAlignment(SwingConstants.LEFT);
txtshort.setHorizontalAlignment(SwingConstants.LEFT); //左对齐
btncreat = new JButton("生成");
btnclear = new JButton("清空");
btncopy = new JButton("复制网址");
panel.add(lbllong);panel.add(txtlong);
panel.add(lblmyshort);panel.add(txtmyshort);panel.add(lblhelp);
panel.add(lblshort);panel.add(txtshort);panel.add(btncopy);
panel.add(btncreat);panel.add(btnclear);panel.add(lblcopy);
txtlong.addKeyListener(new KeyEnterLisener());
txtmyshort.addKeyListener(new KeyEnterLisener());
btncreat.addActionListener(this);
btnclear.addActionListener(this);
btncopy.addActionListener(this);
this.add(panel);
this.setSize(400,165);
this.setLocationRelativeTo(null);
this.setResizable(false);
}
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if (source == btncreat)
{
if (txtmyshort.getText().equals(""))
txtshort.setText(Getdwz(txtlong.getText()));
else txtshort.setText(GetMydwz(txtlong.getText(),txtmyshort.getText()));
}
if (source == btnclear)
{
txtshort.setText("");
txtlong.setText("");
txtmyshort.setText("");
lblcopy.setText("等待复制");
line = null; line2 = null;
}
if (source == btncopy)
{
Clipboard clipboard = getToolkit().getSystemClipboard(); //获得系统剪切板
StringSelection stringSelection = new StringSelection(txtshort.getText());
clipboard.setContents(stringSelection,null);
lblcopy.setText("复制成功");
}
}
public class KeyEnterLisener extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
if (txtmyshort.getText().equals(""))
txtshort.setText(Getdwz(txtlong.getText()));
else txtshort.setText(GetMydwz(txtlong.getText(),txtmyshort.getText()));
}
}
public static String Getdwz(String longwz)
{
try {
String strurl = "url="+longwz;
URL url = new URL("http://dwz.cn/create.php");//伟大的度娘,无需用户登陆授权就可直接调用API
//URL url = new URL("http://126.am/api!shorten.action"); 网易的API必须另外要用户的key做参数,其他门户没有找到公开的API
URLConnection connection = url.openConnection(); //打开url连接
connection.setDoOutput(true); //设置为输出
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.write(strurl); //写入短网址到PORT请求
out.flush();
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = in.readLine())!= null) //得到返回的信息
{
line2 = line.toCharArray();
}
for (int i=0;i<line2.length;i++)
if (line2 == 'h')
{
int k=i,j;
for (j=0;line2!='"';j++)
{
if (line2 != '\\') shortdwz = line2;
else j--;
k++;
}
suitable = new char;
for (int temp=0;temp<j;temp++)
suitable = shortdwz;
System.out.println(suitable);
break;
}
} catch (Exception e) {
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
}
if (shortdwz!='d' || shortdwz!='w' || shortdwz!='z')
{
JOptionPane.showMessageDialog(null,"原网址输入错误或无效!","错误",JOptionPane.ERROR_MESSAGE);
return null;
}
line =new String(suitable);
return line;
}
public static String GetMydwz(String longwz,String myshort)
{
try {
String strmyurl = "url="+longwz+"&alias="+myshort;
URL url = new URL("http://dwz.cn/create.php");//伟大的度娘,无需用户登陆授权就可直接调用API
URLConnection connection = url.openConnection(); //打开url连接
connection.setDoOutput(true); //设置为输出
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.write(strmyurl); //写入短网址到PORT请求
out.flush();
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = in.readLine())!= null) //得到返回的信息
{
line2 = line.toCharArray();
}
for (int i=0;i<line2.length;i++)
if (line2 == 's' && line2 == 't' && line2 == 'a' && line2 == 't')
{
JOptionPane.showMessageDialog(null,"哦豁,运气撇,被人捷足先登了\n这个短网址已经被定义过了或不合法,","哦豁",JOptionPane.ERROR_MESSAGE);
return null;
}
else if (line2 == 'e' && line2 == 'r' && line2 == 'r')
{
JOptionPane.showMessageDialog(null,"哦豁,运气撇,被人捷足先登了\n这个长网址已经映射其他短网址了,","哦豁",JOptionPane.ERROR_MESSAGE);
return null;
}
else if (line2 == 'h' )
{
int k=i,j;
for (j=0;line2!='"';j++)
{
if (line2 != '\\') shortdwz = line2;
else j--;
k++;
}
shortdwz = '\0';
break;
}
} catch (Exception e) {
e.printStackTrace();
}
if (shortdwz!='d' || shortdwz!='w' || shortdwz!='z')
{
JOptionPane.showMessageDialog(null,"原网址输入错误或无效!","错误",JOptionPane.ERROR_MESSAGE);
return null;
}
line =new String(shortdwz);
return line;
}
public static void main(String[] args) throws Exception
{
new dwz().setVisible(true);
}
} VS10一如既往的天坑,尤其是调用系统API的时候:
//VC发送POST请求的时候始终有异常,暂未处理
view plaincopy
/*****************************
* 逸雨清风出品
* CSDN:http://blog.csdn.net/xyydyyqf
* DATE: 2013-6-2
******************************/
#include "stdafx.h"
#include "dwz.h"
#include "afx.h"
#include <afxinet.h>
BOOL WINAPI Main_Proc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
BOOL Main_OnInitDialog(HWND hWnd,HWND hWndFocus,LPARAM lParam);
void Main_OnCommand(HWND hWnd,int id,HWND hwndCtl,UINT codeNotify);
void Main_OnClose(HWND hWnd);
char* Getdwz(CString longwz);
char* Getmydwz(CString longwz,CString myshortwz);
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
DialogBox(hInstance,MAKEINTRESOURCE(IDD_MAINDIALOG),NULL,Main_Proc);
return 0;
}
BOOL WINAPI Main_Proc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
//开始消息测试
HANDLE_MSG(hWnd,WM_INITDIALOG,Main_OnInitDialog);
HANDLE_MSG(hWnd,WM_COMMAND,Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE,Main_OnClose);
//结束消息测试
}
return FALSE;
}
BOOL Main_OnInitDialog(HWND hWnd,HWND hwndFocus,LPARAM lParam)
{
//设置应用程序图标
HICON hIcon = LoadIcon((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),MAKEINTRESOURCE(IDI_ICON3));
SendMessage(hWnd,WM_SETICON,TRUE,(LPARAM)hIcon);
SendMessage(hWnd,WM_SETICON,FALSE,(LPARAM)hIcon);
//添加初始化代码
return TRUE;
}
//主窗口关闭
void Main_OnClose(HWND hWnd)
{
EndDialog(hWnd,0);
}
//主窗口命令响应
void Main_OnCommand(HWND hWnd,int id,HWND hwndCtl,UINT codeNotify)
{
switch(id)
{
case IDCREAT:
char *longwz,*myshortwz,*shortwz;
ZeroMemory(longwz,sizeof(longwz));
ZeroMemory(myshortwz,sizeof(myshortwz));
ZeroMemory(shortwz,sizeof(shortwz));
GetDlgItemText(hWnd,IDC_LONG,longwz,sizeof(longwz));
GetDlgItemText(hWnd,IDC_MYSHORT,myshortwz,sizeof(myshortwz));
if (myshortwz == NULL) shortwz = Getdwz(longwz);
else shortwz = Getmydwz(longwz,myshortwz);
SetDlgItemText(hWnd,IDC_SHORT,shortwz);
break;
case IDCLEAR:
SetDlgItemText(hWnd,IDC_SHORT,"");
SetDlgItemText(hWnd,IDC_LONG,"");
SetDlgItemText(hWnd,IDC_MYSHORT,"");
break;
case IDCOPY:
char* source;
GetDlgItemText(hWnd,IDC_SHORT,source,sizeof(source));
if(OpenClipboard(NULL))
{
/*HGLOBLA clipbuffer;
char *buffer;
EmptyClipboard();
clipbuffer=GlobalAlloc(GMEM_DDESHARE,source.GetLength()+1);
buffer=(char *)GlobalLock(clipbuffer);
strcpy(buffer,LPCSTR(source));
GlobalUnLock(clipbuffer);
SetClipboardData(CF_TEXT,clipbuffer);
CloseClipboard();*/
}
break;
default:break;
}
}
char* Getdwz(CString longwz)
{
char chHeader;
char chData;
char tChars;
memset(tChars,0,128);
CInternetSession session;
CHttpConnection* pConnection=NULL;
CHttpFile* pFile=NULL;
INTERNET_PORT nPort=8080;
strcpy(chHeader,"Content-Type: application/x-www-form-urlencoded");
strcpy(chData,"url=");
strcat(chData,longwz);
pConnection = session.GetHttpConnection("http://dwz.cn",nPort);
pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,"/create.php");
pFile->SendRequest(chHeader,(DWORD)strlen(chHeader),(LPVOID *)chData,strlen(chData));
pFile->Read(tChars,128);
session.Close();
char* shortdwz;
ZeroMemory(shortdwz,sizeof(shortdwz));
for (int i=0;i<sizeof(tChars);i++)
if (tChars == 'h')
{
int k=i,j;
for (j=0;tChars!='"';j++)
{
if (tChars != '\\') shortdwz = tChars;
else j--;
k++;
}
shortdwz = '\0';
break;
}
if (shortdwz!='d' || shortdwz!='w' || shortdwz!='z')
{
MessageBox(NULL,"原网址输入错误或无效!","错误",MB_ICONINFORMATION|MB_OK);
return NULL;
}
return shortdwz;
}
char* Getmydwz(CString longwz,CString myshortwz)
{
char chHeader;
char chData;
char tChars;
memset(tChars,0,128);
CInternetSession session;
CHttpConnection* pConnection=NULL;
CHttpFile* pFile=NULL;
INTERNET_PORT nPort=8080;
strcpy(chHeader,"Content-Type: application/x-www-form-urlencoded");
strcpy(chData,"url=");
strcat(chData,longwz);
strcat(chData,"&alias=");
strcat(chData,myshortwz);
pConnection = session.GetHttpConnection("http://dwz.cn",nPort);
pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,"/create.php");
pFile->SendRequest(chHeader,(DWORD)strlen(chHeader),(LPVOID *)chData,strlen(chData));
pFile->Read(tChars,128);
session.Close();
char* shortdwz;
ZeroMemory(shortdwz,sizeof(shortdwz));
for (int i=0;i<sizeof(tChars);i++)
if (tChars == 's' && tChars == 't' && tChars == 'a' && tChars == 't')
{
MessageBox(NULL,"哦豁,运气撇,被人捷足先登了\n这个短网址已经被定义过了或不合法,","哦豁",MB_ICONINFORMATION|MB_OK;
return NULL;
}
else if (tChars == 'e' && tChars == 'r' && tChars == 'r')
{
MessageBox(NULL,"哦豁,运气撇,被人捷足先登了\n这个长网址已经映射其他短网址了,","哦豁",MB_ICONINFORMATION|MB_OK);
return NULL;
}
else if (tChars == 'h')
{
int k=i,j;
for (j=0;tChars!='"';j++)
{
if (tChars != '\\') shortdwz = tChars;
else j--;
k++;
}
shortdwz = '\0';
break;
}
if (shortdwz!='d' || shortdwz!='w' || shortdwz!='z')
{
MessageBox(NULL,"原网址输入错误或无效!","错误",MB_ICONINFORMATION|MB_OK);
return NULL;
}
return shortdwz;
} 也就是一个base64的正解加反解过程。 谢谢楼主 分享 学习一下!
页:
[1]