Base64编码和解码算法

Base64么新鲜的算法了。只是假设你没从事过页面开发(或者说动态页面开发。尤其是邮箱服务),你都不怎么了解过,仅仅是听起来非常熟悉。

对于黑客来说,Base64与MD5算法有着相同的位置。由于电子邮箱(e-mail)正文就是base64编码的。

那么。我们就一起来深入的探讨一下这个东东吧。

对于一种算法,与其问“它是什么?”,不如问“它实现了什么?”

Base64实现了:将随意字节转为可读字符的编码。

我们知道。除了页面上的文本,计算机中的数据还有非常多是不可见的。那么我们再扯一扯编码的问题吧。

通俗的说,编码就是给某个文字符号边上一个数字序号,计算机在现实这个文字符号(字符)的时候,依据这个序号到字库中查找相应的点阵或矢量数据,

在显示器上“画”出来。(关于点阵和矢量我们就不扯了。不然就真的太远了。

起初的字符编码,没有把汉字、日文、朝鲜文和其它文字包含在内,仅仅有26个英文字母的大写和小写和10个阿拉伯数字。加上一些控制字符和空格,用一个字节

就行全然的编码了。(不要告诉我你不知道2的7次方和2的8次方是多少,一个技术人员为这种问题困扰简直是一种耻辱。)

然而。世界上除了文字还有数据。比方图片、压缩文件、程序等等都是二进制文件。这些文件一样以字节为单位存储数据。这些字节往往不不过2的7次方以内

的可显示的文字字符编码,还有可能是大于127(有符号数小于0)的字节,这些字节没办法用字符显示出来,Base64就是通过某种算法将他们显示出来。

*那么,Base64加密是安全的吗?

没有绝对安全的加密。Base64不是为了安全,而是为了显示。并且Base64是可逆的。也就是说。通过简单的解密就能得到原文。事实上即便是不可逆的MD5算法。

也能够通过明文数据库找出可能的原文(睡到知道e10adc3949ba59abbe56e057f20f883e的原文就是123456)。

*那么,Base64是怎么实现的呢?

事实上非常easy,只是为了URL等特殊用处,Base64选择了下面64个字符作为密文显示,着64个字符都是可显示的,他们是:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

假设密文有不属于他们的字符,那么不是Base64编码或者是山寨版的。

一眼看去就知道是26个字母大写和小写和数字,加上“+”“/”两个符号。“?

*-”因为正則表達式的问题,没有选用,而空格和回车这些是不能显示的。

Base64处理的过程是,以3个字节为一组(3个字节就是24位嘛),每6位扩展成8位得到4个字节(就是32位):

11111111 11111111 11111111 -> 111111 111111 111111 111111 -> 00111111 00111111 00111111 00111111

那么,得到的每个字节,最大也就是2的6次方。

或许你说:哇,小于2的7次方,能够显示了。

事实上不是,得到的这2的6次方式上面那一串字符的索引,也就是说每一个字节的值仅仅是代表它在密文表中的位置。比方

字符“a”的编码是97。 用16进制表示是0x61(VB表示为&H61)。二进制:01100001,由于不足3位。补0得到 00011000 00010000 000……

前两个字节是十进制的24 和 16,那么相应那一串字符中的第24个字符和第16个字符为:YQ(索引从0開始算),那么单独“a”的Base64编码为

YQ==(不足3为的每一个字符直接转为“=”)。简单吧!

有了算法,解码的过程就各位聪明特达的程序猿取思考思考吧,最后C/C++版的编码解码代码贴上。

[cpp] view
plain
copy

  1. /******************************************
  2. Base64编码解码算法 C语言源码
  3. by 虎胆游侠 http://blog.csdn.net/prsniper
  4. ******************************************/
  5. #include <stdio.h>    //注意哦,VC中""是当前路径。<>是系统路径
  6. #include <windows.h>
  7. const char BASE_CODE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  8. //编码,參数:要编码的字符串指针,解码后存放的位置(编码字串长度的4/3),要编码的字符串长度 ->返回结果长度
  9. int fnBase64Encode(char *lpString, char *lpBuffer, int sLen)
  10. {   register int vLen = 0;  //寄存器局部变量,提速
  11. while(sLen > 0)      //处理整个字符串
  12. {   *lpBuffer++ = BASE_CODE[(lpString[0] >> 2 ) & 0x3F];  //右移两位,与00111111是防止溢出,自加
  13. if(sLen > 2) //够3个字符
  14. {   *lpBuffer++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)];
  15. *lpBuffer++ = BASE_CODE[((lpString[1] & 0xF) << 2) | (lpString[2] >> 6)];
  16. *lpBuffer++ = BASE_CODE[lpString[2] & 0x3F];
  17. }else
  18. {   switch(sLen)    //追加“=”
  19. {   case 1:
  20. *lpBuffer ++ = BASE_CODE[(lpString[0] & 3) << 4 ];
  21. *lpBuffer ++ = ‘=‘;
  22. *lpBuffer ++ = ‘=‘;
  23. break;
  24. case 2:
  25. *lpBuffer ++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)];
  26. *lpBuffer ++ = BASE_CODE[((lpString[1] & 0x0F) << 2) | (lpString[2] >> 6)];
  27. *lpBuffer ++ = ‘=‘;
  28. break;
  29. }
  30. }
  31. lpString += 3;
  32. sLen -= 3;
  33. vLen +=4;
  34. }
  35. *lpBuffer = 0;
  36. return vLen;
  37. }
  38. //子函数 - 取密文的索引
  39. inline char GetCharIndex(char c) //内联函数能够省去函数调用过程。提速
  40. {   if((c >= ‘A‘) && (c <= ‘Z‘))
  41. {   return c - ‘A‘;
  42. }else if((c >= ‘a‘) && (c <= ‘z‘))
  43. {   return c - ‘a‘ + 26;
  44. }else if((c >= ‘0‘) && (c <= ‘9‘))
  45. {   return c - ‘0‘ + 52;
  46. }else if(c == ‘+‘)
  47. {   return 62;
  48. }else if(c == ‘/‘)
  49. {   return 63;
  50. }else if(c == ‘=‘)
  51. {   return 0;
  52. }
  53. return 0;
  54. }
  55. //解码,參数:结果,密文,密文长度
  56. int fnBase64Decode(char *lpString, char *lpSrc, int sLen)   //解码函数
  57. {   static char lpCode[4];
  58. register int vLen = 0;
  59. if(sLen % 4)        //Base64编码长度必然是4的倍数,包含‘=‘
  60. {   lpString[0] = ‘\0‘;
  61. return -1;
  62. }
  63. while(sLen > 2)      //不足三个字符。忽略
  64. {   lpCode[0] = GetCharIndex(lpSrc[0]);
  65. lpCode[1] = GetCharIndex(lpSrc[1]);
  66. lpCode[2] = GetCharIndex(lpSrc[2]);
  67. lpCode[3] = GetCharIndex(lpSrc[3]);
  68. *lpString++ = (lpCode[0] << 2) | (lpCode[1] >> 4);
  69. *lpString++ = (lpCode[1] << 4) | (lpCode[2] >> 2);
  70. *lpString++ = (lpCode[2] << 6) | (lpCode[3]);
  71. lpSrc += 4;
  72. sLen -= 4;
  73. vLen += 3;
  74. }
  75. return vLen;
  76. }
  77. void main() //主函数,測试函数
  78. {   char s[] = "a", str[32];
  79. int l = strlen(s);
  80. int i = fnBase64Encode(s, str, l);
  81. printf("fnBase64Encode(\"%s\", str, %d) = \"%s\";\n", s, l, str);
  82. l = fnBase64Decode(s, str, i);
  83. printf("fnBase64Decode(\"%s\", s, %d) = \"%s\";\n", str, i, s);
  84. }

编译为控制台应用程序,执行如图:

原文地址:http://blog.csdn.net/prsniper/article/details/7097643

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-10-07 01:33:28

Base64编码和解码算法的相关文章

win api 实现 base64编码、解码

最近在写小玩意,用到了base64编码,但是考虑到体积大小,网上的多种实现都是利用开源的代码,这就增加了其大小.我想win api能不能实现base64编码.解码.通过一通乱搜,还有收获.就有了以下代码 #pragma comment(lib,"crypt32.lib") LPSTR Base64Encode(LPBYTE lpBuffer,DWORD dwLen) { DWORD dwNeed; LPSTR lpBase64Str ; DWORD dwIndex ; DWORD dw

base64编码、解码的C语言实现

转自:http://www.cnblogs.com/yejianfei/archive/2013/04/06/3002838.html base64是一种基于64个可打印字符来表示二进制数据的表示方法.由于26=64,所以每6位为一个单位,对应某个可打印字符.三个字节共24位,对应于4个base64单位,即3个字节需要用4个可打印字符来表示.它常用来作为电子邮件的传输编码.在base64中的可打印字符包括大写英文字母A-Z,小写英文字母a-z.阿拉伯数字0-9,这样共有62个字符,此外两个可打印

python中base64编码与解码

引言: 在一些项目中,接口的报文是通过base64加密传输的,所以在进行接口自动化时,需要对所传的参数进行base64编码,对拿到的响应报文进行解码: Base64编码是一种"防君子不防小人"的编码方式.广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有"=",生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容易被破解,仅适用于加密非关键信息的场合python2中进行Base64编码和解码&g

PHP安全的URL字符串base64编码和解码

这篇文章主要介绍了PHP安全的URL字符串base64编码和解码,在base64的基础上替换了不安全的一些字符,需要的朋友可以参考下 如果直接使用base64_encode和base64_decode方法的话,生成的字符串可能不适用URL地址.下面的方法可以解决该问题: URL安全的字符串编码: function urlsafe_b64encode($string) {    $data = base64_encode($string);    $data = str_replace(array

java利用Base64编码和解码图片文件

1.编码与解码代码如下所示: import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.image

Python中进行Base64编码和解码

Base64编码是一种“防君子不防小人”的编码方式.广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容易被破解,仅适用于加密非关键信息的场合Python中进行Base64编码和解码>>> import base64>>> s = '我是字符串'>>> a = base64.b64encode(s)>>>

转: Javascript Base64编码与解码

Javascript Base64编码与解码 分类:            JavaScript            2015-02-04 14:25    212人阅读    评论(0)    收藏    举报 转自:http://blog.csdn.net/yanzhibo/article/details/20079943 [javascript] view plaincopy <html> <head> <META HTTP-EQUIV="MSThemeCo

Javascript Base64编码与解码

原文:[转]Javascript Base64编码与解码 <html> <head> <META HTTP-EQUIV="MSThemeCompatible" CONTENT="Yes"> <meta http-equiv="Content-Type" content="text/html; charset=unicode"> <script language="

android Java BASE64编码和解码二:图片的编码和解码

1.准备工作 (1)在项目中集成 Base64 代码,集成方法见第一篇博文:android Java BASE64编码和解码一:基础 (2)添加 ImgHelper 工具类 package com.app21; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import android.graphics.Bitmap; import android