找回密码
 注册
搜索
热搜: 超星 读书 找书
查看: 1557|回复: 8

[【计算机类原创】] 探讨短网址生成原理

[复制链接]
发表于 2014-2-28 16:22:57 | 显示全部楼层 |阅读模式
关于短网址:
回复

使用道具 举报

 楼主| 发表于 2014-2-28 16:23:32 | 显示全部楼层
短网址算法:
    其实短网址的算法跟我们倒没啥关系,因为没有服务器搭建算出来也没用,而且最重要的是这种签名拉~校验拉~算法拉~Hash拉~数学拉什么的。。。正常人是绝对不会感兴趣的。。。。。简而言之,就是通过MD5算法生成签名,然后划分为4段,再进行位运算,再进行字母表索引得到特定字符,最后会生成4个6位字符串,取其中任意一个作为当前短网址。至于重复的问题,首先这个算法算出来以后重复概率应该不高?(咳咳,其实我也不知道高不高,不过每位有26+26+10应该是重复概率很低咯),如果遇到重复的就取另外的字符串嘛,反正先到先得,先映射了的就不用管了。
回复

使用道具 举报

 楼主| 发表于 2014-2-28 16:23:49 | 显示全部楼层
短网址接口:
       对于开发者来说,只需要调用接口获得短网址服务器返回的信息就足够了。目前国内的很多门户网站基本都开通了短网址的服务。
      腾讯: 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字段
回复

使用道具 举报

 楼主| 发表于 2014-2-28 16:24:11 | 显示全部楼层
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。。。。不过每种都很复杂麻烦而且搅在一堆
回复

使用道具 举报

 楼主| 发表于 2014-2-28 16:24:38 | 显示全部楼层
JAVA 在网络方面确实很方便:


[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[100];
    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 == &#39;h&#39;)
          {
            int k=i,j;
            for (j=0;line2[k]!=&#39;"&#39;;j++)
            {
              if (line2[k] != &#39;\\&#39;) shortdwz[j] = line2[k];
              else j--;
              k++;
            }
            suitable = new char[j];
            for (int temp=0;temp<j;temp++)
            suitable[temp] = shortdwz[temp];
            System.out.println(suitable);
            break;
          }
      } catch (Exception e) {
        System.out.println("发送POST请求出现异常!" + e);
        e.printStackTrace();
      }
      if (shortdwz[7]!=&#39;d&#39; || shortdwz[8]!=&#39;w&#39; || shortdwz[9]!=&#39;z&#39;)
      {
        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[2] == &#39;s&#39; && line2[3] == &#39;t&#39; && line2[4] == &#39;a&#39; && line2[5] == &#39;t&#39;)
          {
            JOptionPane.showMessageDialog(null,"哦豁,运气撇,被人捷足先登了\n这个短网址已经被定义过了或不合法,","哦豁",JOptionPane.ERROR_MESSAGE);
            return null;
          }
          else if (line2[2] == &#39;e&#39; && line2[3] == &#39;r&#39; && line2[4] == &#39;r&#39;)
          {
            JOptionPane.showMessageDialog(null,"哦豁,运气撇,被人捷足先登了\n这个长网址已经映射其他短网址了,","哦豁",JOptionPane.ERROR_MESSAGE);
            return null;
          }
        else if (line2 == &#39;h&#39; )
          {
            int k=i,j;
            for (j=0;line2[k]!=&#39;"&#39;;j++)
            {
              if (line2[k] != &#39;\\&#39;) shortdwz[j] = line2[k];
              else j--;
              k++;
            }
            shortdwz[j] = &#39;\0&#39;;
            break;
          }
      } catch (Exception e) {
        e.printStackTrace();
      }
      if (shortdwz[7]!=&#39;d&#39; || shortdwz[8]!=&#39;w&#39; || shortdwz[9]!=&#39;z&#39;)
      {
        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);
    }
  }
回复

使用道具 举报

 楼主| 发表于 2014-2-28 16:25:10 | 显示全部楼层
VS10一如既往的天坑,尤其是调用系统API的时候:

         //VC发送POST请求的时候始终有异常,暂未处理

[cpp] 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[128];
     char chData[128];
     char tChars[128];
   
     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 == &#39;h&#39;)
       {
         int k=i,j;
         for (j=0;tChars[k]!=&#39;"&#39;;j++)
         {
           if (tChars[k] != &#39;\\&#39;) shortdwz[j] = tChars[k];
           else j--;
           k++;
         }
         shortdwz[j] = &#39;\0&#39;;
         break;
       }
     if (shortdwz[7]!=&#39;d&#39; || shortdwz[8]!=&#39;w&#39; || shortdwz[9]!=&#39;z&#39;)
     {
     MessageBox(NULL,"原网址输入错误或无效!","错误",MB_ICONINFORMATION|MB_OK);
     return NULL;
     }
     return shortdwz;   
   }   
   char* Getmydwz(CString longwz,CString myshortwz)
   {
     char chHeader[128];
     char chData[128];
     char tChars[128];
   
     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[2] == &#39;s&#39; && tChars[3] == &#39;t&#39; && tChars[4] == &#39;a&#39; && tChars[5] == &#39;t&#39;)
       {
         MessageBox(NULL,"哦豁,运气撇,被人捷足先登了\n这个短网址已经被定义过了或不合法,","哦豁",MB_ICONINFORMATION|MB_OK;
         return NULL;
       }
       else if (tChars[2] == &#39;e&#39; && tChars[3] == &#39;r&#39; && tChars[4] == &#39;r&#39;)
       {
         MessageBox(NULL,"哦豁,运气撇,被人捷足先登了\n这个长网址已经映射其他短网址了,","哦豁",MB_ICONINFORMATION|MB_OK);
         return NULL;
       }
       else if (tChars == &#39;h&#39;)
       {
         int k=i,j;
         for (j=0;tChars[k]!=&#39;"&#39;;j++)
         {
           if (tChars[k] != &#39;\\&#39;) shortdwz[j] = tChars[k];
           else j--;
           k++;
         }
         shortdwz[j] = &#39;\0&#39;;
         break;
       }
       if (shortdwz[7]!=&#39;d&#39; || shortdwz[8]!=&#39;w&#39; || shortdwz[9]!=&#39;z&#39;)
       {
         MessageBox(NULL,"原网址输入错误或无效!","错误",MB_ICONINFORMATION|MB_OK);
         return NULL;
       }
       return shortdwz;   
   }
回复

使用道具 举报

发表于 2014-3-2 22:37:06 | 显示全部楼层
也就是一个base64的正解加反解过程。
回复

使用道具 举报

发表于 2014-5-19 16:29:16 | 显示全部楼层
谢谢楼主 分享
回复

使用道具 举报

发表于 2018-1-28 12:49:53 | 显示全部楼层
学习一下!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|网上读书园地

GMT+8, 2024-4-19 14:47 , Processed in 0.346620 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表