求一个加密算法,能够实现汉字,数字,字母,标点的加密和解密的(还有加密完的是可见字符的,加密完的长度不能太长于原始的字符串)哪个朋友有给提供点,谢谢了(100分

  • 主题发起人 主题发起人 980
  • 开始时间 开始时间
to jennykiller,

我下载下来了 在哪个文件夹呢啊
 
楼主,你的任务是不可能完成的。关键问题不在压缩还是加密,而在用有限的字符(你要求是可见字符,包括所有键盘上可以输入的字符,总共是93个)去表示无限字符的可能性!这样的加密算法,密文是明文字符的两倍已经是最小的大小了!不可能更小了!

简单的说一个道理,二进制在计算机内部是用高电压和低电压脉冲来表示的,表示0就用一个低电压
0
表示1就用一个高电压
1
这样很容易理解。但是,除非你只想表示这两个数字,否则,你就必须补位。假如,现在我要表示2,那就得出一个高电压一个低电压,于是脉冲就是:
10
但是,你怎么知道这是表示2还是表示一个1和一个0呢?唯一的办法就是,对表示0和1的时候,做补位,即,表示数字0的时候,脉冲发出两个
00
表示数字1的时候,脉冲出 两个
01
表示2的时候,脉冲出两个
10
但是问题来了,如果你要表示3呢?怎么办?继续补位!!!!这和你的密码算法要求不是一样的嘛?你只能有有限的(假设是所有键盘上可见的字符93个)字符,表示无限可能的值(比如,不可见Byte,而一个byte可以有256个不同的值),那你只有用93个字符当中进行补位来完成加密。所以增大一倍已经是最小的长度了,因为电脑里面,无论你怎么压缩,最后得到的都是byte,而你的加密又必须对byte做明文编码,故不太可能实现。

不过,也有变通的,就是先压缩,后加密,比如,10个字符,压缩后得到5个字符,再加密,(扩大一倍),得到10个字符的密文,但是显然不可能让密文比明文少。这里还有一个问题,假如你的压缩算法很好,能打到50%的压缩率,但是,假如你输入的明文只有1个字符呢?再怎么压缩也不可能比1更小了把?压缩比例一般是数据量越大,压缩率越高,如果数据量很小,压缩后的压缩数据会比原来没有压缩前的数据更大!!!!!

唯一的办法,是按照你的要求,遍一个256个完全不同的字符,每个字符代表一个byte,可是,事实上,电脑中最小的单位就是byte,除去不可见字符,就没法用一个byte来包含256个不同的值,因此那也只能补位,变成两个(甚至更多)byte表示一个明文字符!!!加密后的密文也更大了。

这其实也和编程里面的数据类型占用的位数有关,假如你要表示256这个数字,那用一个byte就能表达了;但如果你要存储的数字值是257,那你只好用一个Word类型(一个word类型等于两个连续的byte类型)表示了!这个和你的加密道理是一样的。

假如,你只需要把数字和英文字母做加密(不考虑中文汉字),可以用密码表的方式来加密;即,明文字符加密后对应一个密文字符,比如,A是明文,你有一个加密表,对照这个表翻译,得到A的密文是P,你可以对26个字母逐一生成密码表,这样实现的加密能满足你的要求。但是如果这是在现实中,这样的加密在一定程度上还是可靠的,比如,我给同班的女同学写情书,用这个密码表生成密文寄给她,她再根据密码表还原后得到明文,如果中途信被老师截获了,由于老师没有密码表,在没有足够信息的基础上,她无法破译我们的密文(当然,如果有足够的时间,有足够的多封密文信,老师还是可以通过各种蛛丝马迹逐一破解密码表的)。但是在电脑上又不同了,你的密码表得编译到你的程序里面把?破解的人只要自己随便打26个字母,然后和最终程序生成的密文比对一下,立刻就能得到全部的密码表!加密算法就被破解了!!!是不是太容易了?所以这样的方法也不安全。

综上所述,我认为楼主想得到的这样一个算法是一个不可能完成的任务!呵呵,当然,也许我也有没考虑到的地方,如果我的结论不正确,欢迎朋友们指正,小弟虚心学习!
 
to zqw0117:
楼主的需求是可以做到的。
先说做法:zlib压缩到50%,然后BCD->STR,扩大2倍,基本出来的结果就是原先的长度。
再说存在的几个问题:
1.压缩到50%是个概数,基于统计规律得出的。这个大家没意见吧?至于您说的压缩一个字符'1',太特殊,没有冗余度,当然不可能压缩成0.5字节,故不能作为反例。再次强调一下50%是*统*计*规*律*,bcd->str2倍是恒等值
2.压缩实际上是一种编码算法,加密是加密算法,两者不能混同。如果楼主是做编码,不考虑数据安全性,可以用上面说的base64,zlib,bcd等方法。如果是搞安全,就不能不考虑密文的不可逆性。
3.我估计楼主是想通过SendString之类的方法来做网络传输,是不^_^
 
补充一下,BASE64结果是原文1.5倍,bcd->str结果是原文2倍。BASE64更省一点。

再推荐一种比较“土”的加密方式,就是改变BASE64的字符集顺序,就是'ABC...1234'的字符串,打乱以后就相当于密钥,加密解密用同一套即可。当然密钥最好不要直接出现在内存中,免得被debug,这里的学问就得靠你自己了,呵呵
 
to VictorWoo,
你说的有道理,不过,如果楼主只是要加密一下诸如拨号密码,用户名字,等这样的短字符串,压缩估计也压不了几个字节,最终的效果也不会太理想吧。
 
是的,要看楼主的实际需求。数据量是高并发小数据还是低并发大数据,再采用不同的编码方式。
不然只要一套算法就打遍天下无敌手,其他算法都没用了,也是不可能的事:)
 
不过,反过来,如果楼主要加密一篇txt文档,那么用压缩后再加密应该是不错的选择。不过,用Zip算法,带密码的压缩成Stream,就省去了第二道加密的手续了,应该更符合要求,同时加密强度也足够大。
 
对了,用压缩->再加密的方法生成密文,究竟最后密文长度是否大于明文,取决于“压缩”算法的压缩比概率,压缩比越高,最终的密文越短,压缩比的高低取决于明文的重复数据的多少和明文的长度!考虑的东西真不少。呵呵,估计得用自定义的加密算法了,比如一些有规律的结构,如Record之类的,自定义一个算法来算,如果用通用算法,估计小小的一个record压不了几个字节,最终密文可能还是比明文长许多。
 
我是加密 一个 汉字、数字、字母的一个串 。为什么要 可见字符 发送这个加密的字符串 给 就是这个设备 这个设备对不可见字符 他不能通过去 ,这样就不行了

字符短点 因为发送的条数很密 设备处理能力有限 所以这样 ,

但还的 加密出去

就是这三个原因 才发的帖子
 
楼主,你就用base64算法吧,不过用它算过的代码没法再进行压缩(不信,你用一个base64编码的邮件,用Zip压一下看看,会增大的)。
 
to zqw0117
我开始就说了 除了 base64吗 ,我还的找个别的算法
 
呵呵。楼主可否提供一下您的设备可用的字符集?
[a..z],[A..Z],[0..9] and ?
 
就是键盘上面的字符 就是26个字母 数字 标点等 ,能够看得到的 就可以
 
能够看到的字符就93个,但是一个byte是256个不同的值,用93个字符表示256个不同的值,不用进位是无法完成密码表映射的。
 
看来 难度有啊 ,比我想象的严重的多,开始我还很乐观呢,
 
呵呵,很正常,我记得原来电视里面主持人说过一句话,在街上,随便找13个人,这里面一定有至少2个人属相相同,当时第一感觉是,不可能,可是仔细一想,对啊,只有12个生肖,13个人,必然有一个和另外一个属相相同啊!哈哈,问题就是这样的。
 
在顶两天 没有结果揭贴了
 
哪个朋友有3des 算法的原代码 谢谢了
 
to 楼主:
你可以看一下BASE64算法的原理,网上很多。你就能明白为何两个字节变成3个字节了。
你可以根据你的字符集元素个数,同样地创造出一个BASExxx的最优算法来。程序大体和BASE64一样。
现在上班,没功夫详细说了。相信你看完BASE64的算法之后会很有思路^_^
 
Base64算法原理



Base64算法将输入的字符串或一段数据编码成只含有{''A''-''Z'', ''a''-''z'', ''0''-''9'', ''+'', ''/''}这64个字符的串,''=''用于填充。其编码的方法是,将输入数据流每次取6 bit,用此6 bit的值(0-63)作为索引去查表,输出相应字符。这样,每3个字节将编码为4个字符(3×8 → 4×6);不满4个字符的以''=''填充。

贴在这里,以后忘了的时候方便查阅:)

编码的过程是这样的:第一个字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一个目标字符。然后将第一个字符左移4位加上第二个字符右移4位,即获得第二个目标字符。再将第二个字符左移2位加上第三个字符右移6位,获得第三个目标字符。最后取第三个字符的右6位即获得第四个目标字符。在以上的每一个步骤之后,再把结果与 0x3F 进行 AND 位操作,就可以得到编码后的字符了。
实现如下:
00001
00013 #include <ctype.h>
00014
00015
00016 static const char base64digits[] =
00017 &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&quot;;
00018
00019 #define BAD -1
00020 static const char base64val[] = {
00021 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
00022 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
00023 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
00024 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
00025 BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
00026 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
00027 BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00028 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD
00029 };
00030 #define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
00031
00039 void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
00040 {
00041 for (; inlen >= 3; inlen -= 3)
00042 {
00043 *out++ = base64digits[in[0] >> 2];
00044 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
00045 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
00046 *out++ = base64digits[in[2] & 0x3f];
00047 in += 3;
00048 }
00049
00050 if (inlen > 0)
00051 {
00052 unsigned char fragment;
00053
00054 *out++ = base64digits[in[0] >> 2];
00055 fragment = (in[0] << 4) & 0x30;
00056
00057 if (inlen > 1)
00058 fragment |= in[1] >> 4;
00059
00060 *out++ = base64digits[fragment];
00061 *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
00062 *out++ = '=';
00063 }
00064
00065 *out = '/0';
00066 }
00067
00075 int from64tobits(char *out, const char *in)
00076 {
00077 int len = 0;
00078 register unsigned char digit1, digit2, digit3, digit4;
00079
00080 if (in[0] == '+' && in[1] == ' ')
00081 in += 2;
00082 if (*in == '/r')
00083 return(0);
00084
00085 do {
00086 digit1 = in[0];
00087 if (DECODE64(digit1) == BAD)
00088 return(-1);
00089 digit2 = in[1];
00090 if (DECODE64(digit2) == BAD)
00091 return(-1);
00092 digit3 = in[2];
00093 if (digit3 != '=' && DECODE64(digit3) == BAD)
00094 return(-1);
00095 digit4 = in[3];
00096 if (digit4 != '=' && DECODE64(digit4) == BAD)
00097 return(-1);
00098 in += 4;
00099 *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
00100 ++len;
00101 if (digit3 != '=')
00102 {
00103 *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
00104 ++len;
00105 if (digit4 != '=')
00106 {
00107 *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
00108 ++len;
00109 }
00110 }
00111 } while (*in && *in != '/r' && digit4 != '=');
00112
00113 return (len);
00114 }
 

Similar threads

D
回复
0
查看
909
DelphiTeacher的专栏
D
D
回复
0
查看
704
DelphiTeacher的专栏
D
D
回复
0
查看
666
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部