别人给的一段VB的字符串加解密代码,哪位大虾能移植一下?
' 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




