CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  基础类

别人给的一段VB的字符串加解密代码,哪位大虾能移植一下?

楼主knf(CTO-首席打字员)2001-08-20 16:00:32 在 C++ Builder / 基础类 提问

'   Encipher   the   text   using   the   pasword.  
   
  Sub   Cipher(ByVal   password   As   String,   ByVal   from_text   As   String,   to_text   As   String)  
  Const   MIN_ASC   =   32                           '   Space.  
  Const   MAX_ASC   =   126                         '   ~.  
  Const   NUM_ASC   =   MAX_ASC   -   MIN_ASC   +   1  
   
  Dim   offset   As   Long  
  Dim   str_len   As   Integer  
  Dim   i   As   Integer  
  Dim   ch   As   Integer  
   
          '   Initialize   the   random   number   generator.  
   
          offset   =   NumericPassword(password)  
          Rnd   -1  
          Randomize   offset  
   
          '   Encipher   the   string.  
   
          str_len   =   Len(from_text)  
          For   i   =   1   To   str_len  
                  ch   =   Asc(Mid$(from_text,   i,   1))  
                  If   ch   >=   MIN_ASC   And   ch   <=   MAX_ASC   Then  
                          ch   =   ch   -   MIN_ASC  
                          offset   =   Int((NUM_ASC   +   1)   *   Rnd)  
                          ch   =   ((ch   +   offset)   Mod   NUM_ASC)  
                          ch   =   ch   +   MIN_ASC  
                          to_text   =   to_text   &   Chr$(ch)  
                  End   If  
          Next   i  
  End   Sub  
   
  '   Encipher   the   text   using   the   pasword.  
   
  Sub   Decipher(ByVal   password   As   String,   ByVal   from_text   As   String,   to_text   As   String)  
  Const   MIN_ASC   =   32                               '   Space  
  Const   MAX_ASC   =   126                             '   ~  
  Const   NUM_ASC   =   MAX_ASC   -   MIN_ASC   +   1  
   
  Dim   offset   As   Long  
  Dim   str_len   As   Integer  
  Dim   i   As   Integer  
  Dim   ch   As   Integer  
   
          '   Initialize   the   random   number   generator.  
   
          offset   =   NumericPassword(password)  
          Rnd   -1  
          Randomize   offset  
   
          '   Encipher   the   string.  
   
          str_len   =   Len(from_text)  
          For   i   =   1   To   str_len  
                  ch   =   Asc(Mid$(from_text,   i,   1))  
                  If   ch   >=   MIN_ASC   And   ch   <=   MAX_ASC   Then  
                          ch   =   ch   -   MIN_ASC  
                          offset   =   Int((NUM_ASC   +   1)   *   Rnd)  
                          ch   =   ((ch   -   offset)   Mod   NUM_ASC)  
                          If   ch   <   0   Then   ch   =   ch   +   NUM_ASC  
                          ch   =   ch   +   MIN_ASC  
                          to_text   =   to_text   &   Chr$(ch)  
                  End   If  
          Next   i  
  End   Sub  
   
   
  '   Translate   a   password   into   an   offset   value.  
   
  Function   NumericPassword(ByVal   password   As   String)   As   Long  
  Dim   value   As   Long  
  Dim   ch   As   Long  
  Dim   shift1   As   Long  
  Dim   shift2   As   Long  
  Dim   i   As   Integer  
  Dim   str_len   As   Integer  
   
          str_len   =   Len(password)  
          For   i   =   1   To   str_len  
                  '   Add   the   next   letter.  
   
                  ch   =   Asc(Mid$(password,   i,   1))  
                  value   =   value   Xor   (ch   *   2   ^   shift1)  
                  value   =   value   Xor   (ch   *   2   ^   shift2)  
   
                  '   Change   the   shift   offsets.  
   
                  shift1   =   (shift1   +   7)   Mod   19  
                  shift2   =   (shift2   +   13)   Mod   23  
          Next   i  
          NumericPassword   =   value  
  End   Function  
   
  问题点数:100、回复次数:17Top

1 楼knf(CTO-首席打字员)回复于 2001-08-20 16:42:23 得分 0

up~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Top

2 楼ALNG(?)回复于 2001-08-20 17:41:09 得分 100

这个好像很白吧,   一句一句硬译过来就可以了。  
   
  void   Cipher(String   password,   String   from_text,   String   to_text)  
  {  
          const   int   MIN_ASC   =   32,   MAX_ASC   =   126,   NUM_ASC   =   MAX_ASC   -   MIN_ASC   +1;  
   
          long   offset;  
          int   str_len,   i,   ch;  
   
          //   Initialize   the   random   number   generator.  
          offset   =   NumericPassword(password);  
          //Rnd   -1   //这一句刚好没资料查  
   
          srand(offset)  
   
          //'   Encipher   the   string.  
   
          str_len   =   from_text.Length();  
          for(i   =   1   ;i<=str_len;   i++){  
                  ch   =   *(from_text.SubString(i,   1).c_str());  
                  if(ch   >=   MIN_ASC   &&   ch   <=   MAX_ASC)   {  
                          ch   -=   MIN_ASC  
                          offset   =   (NUM_ASC   +   1)   *   rand();  
                          ch   =   (ch   +   offset)   %   NUM_ASC;  
                          ch   +=   MIN_ASC  
                          to_text   =   to_text   +   char(ch);  
                  }  
          }  
  }  
   
  //Encipher   the   text   using   the   pasword.  
   
  void   Decipher(String   password,String   from_text,     String   to_text   As)  
  {  
          const   int   MIN_ASC   =   32,   MAX_ASC   =   126,   NUM_ASC   =   MAX_ASC   -   MIN_ASC   +1;  
   
          long   offset;  
          int   str_len,   i,   ch;  
   
          //   Initialize   the   random   number   generator.  
          offset   =   NumericPassword(password);  
          //Rnd   -1   //这一句刚好没资料查  
   
          srand(offset);  
   
          //   Encipher   the   string.  
   
          str_len   =   from_text.Length();  
          for(i   =   1;   i<=str_len;   i++){  
                  ch   =   *(from_text.SubString(i,   1).c_str())  
                  if   (ch   >=   MIN_ASC   And   ch   <=   MAX_ASC){  
                          ch   -=   MIN_ASC  
                          offset   =   (NUM_ASC   +   1)   *   rand();  
                          ch   =   ((ch   -   offset)   %   NUM_ASC);  
                          if(ch<   0)ch   +=   NUM_ASC;  
                          ch   +=   MIN_ASC;  
                          to_text   +=   char(ch);  
                  }  
          }  
  }  
   
   
  //   Translate   a   password   into   an   offset   value.  
   
  long   NumericPassword(String   password)  
  {  
          long   value,   ch,shift1,shift2;  
          int   i,   str_len;  
   
          str_len   =   password.Length();  
          for(i   =   1;   i<=str_len;   i++){  
                  //   Add   the   next   letter.  
   
                  ch   =   *(password.SubString(i,   1).c_str());  
                  value   ^=   ch   *   pow(2,shift1);  
                  value   ^=   ch   *   pow(2,shift2);  
   
                  //   Change   the   shift   offsets.  
   
                  shift1   =   (shift1   +   7)   %   19  
                  shift2   =   (shift2   +   13)   %   23  
          }//Next   i  
          return   value;  
  }//End   Function  
  Top

3 楼LuoGD(抢第一楼)回复于 2001-08-20 18:01:32 得分 0

upTop

4 楼ALNG(?)回复于 2001-08-20 18:09:10 得分 0

还是没有测试,  
   
  void   DoCipher(const   String   pwd,   const   String   from,   String   to,bool   cipher)  
  {  
          const   int   MIN_ASC   =   32,   MAX_ASC   =   126,   NUM_ASC   =   MAX_ASC   -   MIN_ASC   +1;  
   
          long   offset;  
          int   str_len,   i,   ch;  
   
          //   Initialize   the   random   number   generator.  
          offset   =   NumericPassword(password);  
          //Rnd   -1   ??  
          srand(offset);  
   
          //process   the   string.  
          str_len   =   from_text.Length();  
          for(i   =   1;   i<=str_len;   i++){  
                  ch   =   *(from_text.SubString(i,   1).c_str());  
                  if(ch   >=   MIN_ASC   &&   ch   <=   MAX_ASC)   {  
                          ch   -=   MIN_ASC  
                          offset   =   (NUM_ASC   +   1)   *   rand();  
                          ch   =   (ch   +   (cipher   ?   offset   :   -offset))   %   NUM_ASC;  
                          ch   +=   MIN_ASC  
                          to_text   =   to_text   +   char(ch);  
                  }  
          }  
  }  
   
  void   Cipher(String   password,   String   from_text,   String   to_text)  
  {  
          DoCipher(password,from_text,to_text,true);  
  }  
   
  void   Decipher(String   password,String   from_text,     String   to_text   As)  
  {  
          DoCipher(password,from_text,to_text,false);  
  }  
  //   Translate   a   password   into   an   offset   value.  
   
  long   NumericPassword(String   password)  
  {  
          long   value,   ch,shift1,shift2;  
          int   i,   str_len;  
   
          str_len   =   password.Length();  
          for(i   =   1;   i<=str_len;   i++){  
                  //   Add   the   next   letter.  
                  ch   =   *(password.SubString(i,   1).c_str());  
                  value   ^=   ch   *   (1<<shift1);  
                  value   ^=   ch   *   (1<<shift2);  
                  //   Change   the   shift   offsets.  
                  shift1   =   (shift1   +     7)   %   19;  
                  shift2   =   (shift2   +   13)   %   23;  
          }  
          return   value;  
  }  
  Top

5 楼lluunn007(书生)回复于 2001-08-20 18:23:35 得分 0

阿良     猛  
  VB也会啊。Top

6 楼knf(CTO-首席打字员)回复于 2001-08-20 20:43:32 得分 0

我测试一下。  
  那个Rnd   -1到底是什么意思?  
  我在vb中运行了这段程序,没有它是不行的。Top

7 楼knf(CTO-首席打字员)回复于 2001-08-20 20:59:26 得分 0

Rnd是返回一个大于0小于1的随机数,但Rnd-1是什么意思?vb中可以这样写,以前从没看到过。  
  这个随机数是用来做什么的,还是看不懂。Top

8 楼knf(CTO-首席打字员)回复于 2001-08-20 21:13:56 得分 0

Rnd-1和Randomize   offset好像是用来保证两次取得相同的随机数的。用任意一个小数换掉c++中的两处rand(),就可以通过了,只是加密的安全性又低了些。  
  C++中有没有类似的办法?Top

9 楼lonelyxxf()回复于 2001-08-20 22:40:44 得分 0

不行啊,rand()换成常数就失去意义了。  
  还有ch   =   *(password.SubString(i,   1).c_str());好像和原表达式的意义不同吧?Top

10 楼shak(孙诗美)回复于 2001-08-21 00:59:06 得分 0

请给我分,我已经没有分了.就不能提问了,不幸的大白鲨  
  请帮助我  
  http://www.csdn.net/expert/TopicView.asp?id=244358   速成高手的问题????????100000风  
  http://www.csdn.net/expert/TopicView.asp?id=246638   大白鲨-高分请教  
  http://www.csdn.net/expert/TopicView.asp?id=224469   shak:报考2001年中级程序员和初级程序员请进!!!!  
  http://www.csdn.net/expert/TopicView.asp?id=224471   提议大家一起来汉化C++BUILDER  
  http://www.csdn.net/expert/TopicView.asp?id=244357   《C++Builder编程技巧全集》之“系统函数"Top

11 楼ALNG(?)回复于 2001-08-21 09:15:37 得分 0

>>还有ch   =   *(password.SubString(i,   1).c_str());好像和原表达式的意义不同吧?    
  原文,  
  ch   =   Asc(Mid$(from_text,   i,   1))  
  其中Mid$(from_text,i,1)是从from_text的第i个字节开始取1个,   等价于  
  from_text.SubString(i,1);  
   
  令等到得String为tmp;(假定为'a');  
   
  Asc(tmp)表示取tmp的第一个(市机上只有一个)字符的ASC值,  
   
  在C++中,通过tmp.c_str();得到了'a'\0;  
  *(tmp.c_str())得到了'a'的ASC值。  
   
  他们正好是等价的。当然C++中有更有效的实现方法。  
   
  刚买了个D版的VB,   不过好像装不上。                 Top

12 楼ALNG(?)回复于 2001-08-21 09:43:45 得分 0

>>         Rnd   -1  
  >>         Randomize   offset  
   
  的意图是以offset为种子初始化随机数生成器。我不敢说C++有与其完全兼容的库函数(比如用  
  vb的程序加密,用对应的C++程序解密),但是如果是配套使用,我上面的程序已经完整的体现  
  了源程序的意图:  
  以下是我测试srand,   和rand正常工作的代码:  
   
  //---------------------------------------------------------------------------  
   
  #include   <vcl.h>  
  #pragma   hdrstop  
  #include   <iostream>  
   
  //---------------------------------------------------------------------------  
   
  using   namespace   std;  
  #pragma   argsused  
  int   main(int   argc,   char*   argv[])  
  {  
          unsigned   int   seeds[2]={1000,5000};  
   
          for(int   i=0;   i<2;   i++){  
                  for(int   j=0;   j<2;   j++){  
                          cout<<"Using   "<<seeds[i]<<"   as   seed,   the   first   ten   r.n.   goes   as:\n";  
                          srand(seeds[i]);  
                          for(int   k=0;   k<10;   k++)  
                                  cout<<rand()<<'   ';  
                          cout<<endl;  
                  }  
          }  
        int   i;  
          cin>>i;  
          return   0;  
  }  
  //---------------------------------------------------------------------------  
   
  运行结果:  
  Using   1000   as   seed,   the   first   ten   r.n.   goes   as:  
  14062   5795   15161   15600   27360   32062   11254   24761   8516   27734  
  Using   1000   as   seed,   the   first   ten   r.n.   goes   as:  
  14062   5795   15161   15600   27360   32062   11254   24761   8516   27734  
  Using   5000   as   seed,   the   first   ten   r.n.   goes   as:  
  3388   28456   31877   8101   24639   772   18658   32610   16323   14169  
  Using   5000   as   seed,   the   first   ten   r.n.   goes   as:  
  3388   28456   31877   8101   24639   772   18658   32610   16323   14169  
   
  运行结果表明srand(offset)可以正常初始化random   number   generator,   随后的对rand()的  
  调用产生的随机数序列对于确定的offset是确定的,这体现了可还原性;对不同的offset,序列  
  则打不相同,这体现了依赖于offset(offset又依赖于password)的加密和解密,从而使加密具有  
  一定程度的可信性。  
   
  VB装不成,不过我的估计是非常可能两者可以混用。  
          Top

13 楼ALNG(?)回复于 2001-08-21 11:14:19 得分 0

测试并修改了几处错误,现在可以运行了。  
   
  //---------------------------------------------------------------------------  
   
  #include   <vcl.h>  
  #pragma   hdrstop  
   
  #include   "Unit1.h"  
  //---------------------------------------------------------------------------  
  #pragma   package(smart_init)  
  #pragma   resource   "*.dfm"  
  TForm1   *Form1;  
  //--------------------------------------  
  long   NumericPassword(String   password)  
  {  
          long   value=0,   ch=0,shift1=0,shift2=0;   //与VB不同,此处不会自动初始化为0  
          int   i,   str_len;  
   
          str_len   =   password.Length();  
          for(i   =   1;   i<=str_len;   i++){  
                  //   Add   the   next   letter.  
                  ch   =   *(password.SubString(i,   1).c_str());  
                  value   ^=   ch   *   (1<<shift1);  
                  value   ^=   ch   *   (1<<shift2);  
                  //   Change   the   shift   offsets.  
                  shift1   =   (shift1   +     7)   %   19;  
                  shift2   =   (shift2   +   13)   %   23;  
          }  
          return   value;  
  }  
  //----------------------------------------------------------------------  
  void   DoCipher(const   String   pwd,   const   String   from,   String&   to,bool   cipher)  
  {  
          const   int   MIN_ASC   =   32,   MAX_ASC   =   126,   NUM_ASC   =   MAX_ASC   -   MIN_ASC   +1;  
   
          long   offset,str_len,   ch;  
   
          //   Initialize   the   random   number   generator.  
          offset   =   NumericPassword(pwd);  
   
          srand(offset);  
   
          //process   the   string.  
          str_len   =   from.Length();  
          for(int   i   =   1;   i<=str_len;   i++){  
                  ch   =   *(from.SubString(i,   1).c_str());  
                  if(ch   >=   MIN_ASC   &&   ch   <=   MAX_ASC)   {  
                          ch   -=   MIN_ASC;  
                          offset   =   (NUM_ASC   +   1)   *   ((float)rand()/RAND_MAX);  
                          ch   =   (ch   +   (cipher   ?   offset   :   -offset))   %   NUM_ASC;  
                          if(!cipher   &&   ch<0)   ch   +=   NUM_ASC;   //此处原来漏了一句  
                          ch   +=   MIN_ASC;  
                          to   +=   char(ch);  
                  }  
          }  
  }  
   
  void   Cipher(String   password,   String   from_text,   String&   to_text)  
  {  
          DoCipher(password,from_text,to_text,true);  
  }  
   
  void   Decipher(String   password,String   from_text,   String&   to_text)  
  {  
          DoCipher(password,from_text,to_text,false);  
  }  
  //   Translate   a   password   into   an   offset   value.  
   
  //---------------------------------------------------------------------------  
  __fastcall   TForm1::TForm1(TComponent*   Owner)  
          :   TForm(Owner)  
  {  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TForm1::Button1Click(TObject   *Sender)  
  {  
          String   s;  
          Cipher("greatbcb",Memo1->Lines->Text,   s);  
          Memo2->Lines->Text=s;  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TForm1::Button2Click(TObject   *Sender)  
  {  
          String   s;  
          Decipher("greatbcb",Memo2->Lines->Text,s);  
          Memo1->Lines->Text=s;  
  }  
  //---------------------------------------------------------------------------  
  Top

14 楼knf(CTO-首席打字员)回复于 2001-08-21 13:39:49 得分 0

不错,不错,我要加分了。Top

15 楼wildhorse01(ChinaBCB之雨中漫步)回复于 2001-08-21 14:32:55 得分 0

好Top

16 楼ALNG(?)回复于 2001-08-21 15:08:49 得分 0

再看看这个实现,   效率比VB下的对应物要高得多,   这才是C++处理字符串的方式:  
   
  void   DoCipher(const   String   pwd,   const   String   from,   String&   to,bool   cipher)  
  {  
          const   int   MIN_ASC   =   32,   MAX_ASC   =   126,   NUM_ASC   =   MAX_ASC   -   MIN_ASC   +1;  
   
          long   offset   ,   ch;  
   
          //   Initialize   the   random   number   generator.  
          offset   =   NumericPassword(pwd);  
   
          srand(offset);  
   
          //process   the   string.  
          for(   char   *   tmp=from.c_str();   (ch=*tmp)!=NULL;   tmp++){  
                  if(ch   >=   MIN_ASC   &&   ch   <=   MAX_ASC)   {  
                          ch   -=   MIN_ASC;  
                          offset   =   (NUM_ASC   +   1)   *   ((float)rand()/RAND_MAX);  
                          ch   =   (ch   +   (cipher   ?   offset   :   -offset))   %   NUM_ASC;  
                          if(!cipher   &&   ch<0)   ch   +=   NUM_ASC;  
                          ch   +=   MIN_ASC;  
                          to   +=   char(ch);  
                  }  
          }  
  }  
   
  >>lluunn007(玉笛书生)   
   
  多谢!   刚才忙着回答问题,   用完了3次机会,   没法向你致意了。  
  你的QQ?  
   
  Top

17 楼knf(CTO-首席打字员)回复于 2001-08-21 16:55:06 得分 0

我拷贝下来慢慢看:)Top

相关问题

  • 解密字符串
  • 字符串的加密与解密
  • 字符串加密和解密函数
  • vb字符串的结构问题
  • 关于VB的字符串的操作!
  • VB里字符串处理的怪事
  • VB中如何拆分字符串?
  • VB中对字符串的操作
  • 求翻译一个字符串(vb->c#)
  • vb字符串编码问题

关键词

  • c++
  • vb
  • 解密
  • asc
  • offset
  • numericpassword
  • ch
  • 初始化
  • goes
  • tmp

得分解答快速导航

  • 帖主:knf
  • ALNG

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo