将 Ord 限制为仅字母
Limiting Ord to letters only
我正在尝试为学校项目创建一个简单的加密方法,想法是通过使用用户输入的数字增加它的 ascii 来更改字符,然后将其替换回去。
所以我的问题是当我这样做时,它有效,但它也包含像 %$! ...ETC。
我想要做的是将 Ord 函数限制为仅字母,例如,如果用户输入数字 100,但字母表中只有 26 个字母,它将不断循环遍历这 26 个字母,直到达到第 100 个。
希望我足够清楚大声笑
这是我到目前为止所拥有的,整个代码的一部分:
Procedure Crypting( Var cryptFile : Text; tempVar2 : String; pNumber: Integer);
Begin
Writeln('Enter P : ');
Readln(P);
Reset( cryptFile );
For i:= 1 to length(tempVar2) do
Write(Chr(Ord(tempVar2[i])+P));
End;
您似乎希望实施 Caesar cipher。
首先,您需要使用if
语句来检查当前字符是否为字母。如果是,你就改造它;如果没有,你保持原样。
其次,仅仅在字符编码上加上P
是不够的。虽然它适用于 A
和 P = 3
,生成 D
,但对于 Y
和 P = 3
会发生什么?您需要使用 modular arithmetic 才能得到 Y → Z → A → B
.
第三,在编程中,合理构造代码并适当地重构它很重要。目前,您混合输入和转换。你应该把它们分开。如果您创建一个 Caesar
函数,您可以在每次需要执行凯撒密码时使用它。
如果我们还需要同时支持大小写字母,最好使用 case
结构而不是 if .. else if .. else
结构。
综合起来:
function Caesar(const S: string; N: Integer): string; // slow
var
i: Integer;
begin
Result := '';
for i := 1 to Length(S) do
case S[i] of
'A'..'Z':
Result := Result + Chr(Ord('A') + (Ord(S[i]) - Ord('A') + N) mod 26);
'a'..'z':
Result := Result + Chr(Ord('a') + (Ord(S[i]) - Ord('a') + N) mod 26);
else
Result := Result + S[i];
end;
end;
此函数有效,但从性能的角度来看并不是最佳的,因为您需要为每次迭代分配堆。最好分配一次结果字符串,然后只填充它:
function Caesar(const S: string; N: Integer): string;
var
i: Integer;
begin
SetLength(Result, Length(S));
for i := 1 to Length(S) do
case S[i] of
'A'..'Z':
Result[i] := Chr(Ord('A') + (Ord(S[i]) - Ord('A') + N) mod 26);
'a'..'z':
Result[i] := Chr(Ord('a') + (Ord(S[i]) - Ord('a') + N) mod 26);
else
Result[i] := S[i];
end;
end;
一个完整的例子:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
function Caesar(const S: string; N: Integer): string;
var
i: Integer;
begin
SetLength(Result, Length(S));
for i := 1 to Length(S) do
case S[i] of
'A'..'Z':
Result[i] := Chr(Ord('A') + (Ord(S[i]) - Ord('A') + N) mod 26);
'a'..'z':
Result[i] := Chr(Ord('a') + (Ord(S[i]) - Ord('a') + N) mod 26);
else
Result[i] := S[i];
end;
end;
var
s: string;
N: Integer;
begin
Writeln('Please enter a string to transform:');
Readln(s);
Writeln('Please enter shift size:');
Readln(N);
Writeln;
Writeln('Result: ', Caesar(s, N));
Writeln;
Writeln('Thank you for using this program! Have a nice day!');
Writeln('Press Return to exit.');
Readln;
end.
(精确的程序结构取决于您使用的 Pascal 的种类 -- Pascal 有很多种。)
截图:
我正在尝试为学校项目创建一个简单的加密方法,想法是通过使用用户输入的数字增加它的 ascii 来更改字符,然后将其替换回去。 所以我的问题是当我这样做时,它有效,但它也包含像 %$! ...ETC。 我想要做的是将 Ord 函数限制为仅字母,例如,如果用户输入数字 100,但字母表中只有 26 个字母,它将不断循环遍历这 26 个字母,直到达到第 100 个。 希望我足够清楚大声笑 这是我到目前为止所拥有的,整个代码的一部分:
Procedure Crypting( Var cryptFile : Text; tempVar2 : String; pNumber: Integer);
Begin
Writeln('Enter P : ');
Readln(P);
Reset( cryptFile );
For i:= 1 to length(tempVar2) do
Write(Chr(Ord(tempVar2[i])+P));
End;
您似乎希望实施 Caesar cipher。
首先,您需要使用if
语句来检查当前字符是否为字母。如果是,你就改造它;如果没有,你保持原样。
其次,仅仅在字符编码上加上P
是不够的。虽然它适用于 A
和 P = 3
,生成 D
,但对于 Y
和 P = 3
会发生什么?您需要使用 modular arithmetic 才能得到 Y → Z → A → B
.
第三,在编程中,合理构造代码并适当地重构它很重要。目前,您混合输入和转换。你应该把它们分开。如果您创建一个 Caesar
函数,您可以在每次需要执行凯撒密码时使用它。
如果我们还需要同时支持大小写字母,最好使用 case
结构而不是 if .. else if .. else
结构。
综合起来:
function Caesar(const S: string; N: Integer): string; // slow
var
i: Integer;
begin
Result := '';
for i := 1 to Length(S) do
case S[i] of
'A'..'Z':
Result := Result + Chr(Ord('A') + (Ord(S[i]) - Ord('A') + N) mod 26);
'a'..'z':
Result := Result + Chr(Ord('a') + (Ord(S[i]) - Ord('a') + N) mod 26);
else
Result := Result + S[i];
end;
end;
此函数有效,但从性能的角度来看并不是最佳的,因为您需要为每次迭代分配堆。最好分配一次结果字符串,然后只填充它:
function Caesar(const S: string; N: Integer): string;
var
i: Integer;
begin
SetLength(Result, Length(S));
for i := 1 to Length(S) do
case S[i] of
'A'..'Z':
Result[i] := Chr(Ord('A') + (Ord(S[i]) - Ord('A') + N) mod 26);
'a'..'z':
Result[i] := Chr(Ord('a') + (Ord(S[i]) - Ord('a') + N) mod 26);
else
Result[i] := S[i];
end;
end;
一个完整的例子:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
function Caesar(const S: string; N: Integer): string;
var
i: Integer;
begin
SetLength(Result, Length(S));
for i := 1 to Length(S) do
case S[i] of
'A'..'Z':
Result[i] := Chr(Ord('A') + (Ord(S[i]) - Ord('A') + N) mod 26);
'a'..'z':
Result[i] := Chr(Ord('a') + (Ord(S[i]) - Ord('a') + N) mod 26);
else
Result[i] := S[i];
end;
end;
var
s: string;
N: Integer;
begin
Writeln('Please enter a string to transform:');
Readln(s);
Writeln('Please enter shift size:');
Readln(N);
Writeln;
Writeln('Result: ', Caesar(s, N));
Writeln;
Writeln('Thank you for using this program! Have a nice day!');
Writeln('Press Return to exit.');
Readln;
end.
(精确的程序结构取决于您使用的 Pascal 的种类 -- Pascal 有很多种。)
截图: