一个非常简单的方法是将字符串通过ROT13方法进行混淆并存储。
procedure ROT13(var Str: string);
const
OrdBigA = Ord('A');
OrdBigZ = Ord('Z');
OrdSmlA = Ord('a');
OrdSmlZ = Ord('z');
var
i, o: integer;
begin
for i := 1 to length(Str) do
begin
o := Ord(Str[i]);
if InRange(o, OrdBigA, OrdBigZ) then
Str[i] := Chr(OrdBigA + (o - OrdBigA + 13) mod 26)
else if InRange(o, OrdSmlA, OrdSmlZ) then
Str[i] := Chr(OrdSmlA + (o - OrdSmlA + 13) mod 26);
end;
end;
function ROT13fun(const Str: string): string;
begin
result := Str;
ROT13(result);
end;
const
ObfuscatedString = 'Guvf vf n frperg zrffntr.';
procedure TForm4.FormCreate(Sender: TObject);
begin
ShowMessage(ROT13fun(ObfuscatedString));
end;
稍微高级一些的方法是使用凯撒密码或维吉尼亚密码来进行操作。
要获得用于源代码中的混淆字符串,您可以使用像我的
Rejbrand文本编辑器或
Wolfram|Alpha这样的良好文本编辑器。
更新
ROT13 很容易被解密,但根据情况也许已经足够了!至少在二进制文件中查找字符串会变得非常困难。需要付出真正的努力才能获得这些字符串。毕竟,在十六进制编辑器/文本编辑器中,普通用户甚至不会看到二进制文件! 凯撒密码是 ROT13 密码的一个非常简单的推广,并且也很容易被解密。实际上,只有 25 种不同的“密码”。 维吉尼亚密码则更加棘手,并需要一些真正的努力去破译(特别是因为您无法确切知道字符串在二进制文件中的位置)。
作为例子,下面是一个使用维吉尼亚密码混淆的字符串:
Xlc tsrgcdk sj ‘vrivem’ mw cei sd kli acirivqhfriw cw qsbsir tfmjmgw, rrh biimrk hyi pygk gilhlvc mf ws, wk leq rpws pvgsqc fj agrvwtvcou mrrsiiwx we izcfp-hew cmji, rpxlmixl ml r piqg xigfbzgep zrrkyyuv. Mlrvih, hyi qmrvvr qctmixw vbtpmwkw ilsikc qclvgiq ks wsqy er soxirr klex hyi ilhzvi cbmmvslavrx mt xli Srvxl wj irboekivcr. Mr hymw qstxmsl, ai uwcp mljvwxmeoki xfs tlcqwtep zojmw mt xli seivkw tsrgcdk.
当然,可以将密码扩展到数字和特殊字符,包括空格。 它还可以混合大写字母和小写字母。那么它将非常难以破解(尽管有可能)。 如果密码是已知单词,则破译会更容易,在字典中可以找到该单词。 如果不是单词,则更安全。
上面的文本使用一个可以在足够大的字典中找到的单词进行混淆。 下面的文本使用无意义的字符串作为密码进行混淆:
Miwzvjfy m vjsy-tombox zguol ap ahqovz d uwk sbze w conz pe biusvth pagh h njsx. Io puvyeq, fl cjsx xic vmovdq zappzjvz, vnjnatl frcb vy dtmd vhxkt fto babtf davf. Uuxlhqb, khk aa dbn eumsuzq, auk saed vlpnbuuo ywlemz ue pnyl ttmxv. Pa ghof, fl cjsx kmbbzk atmd wv sfjtmxcl rtfysk cb yuta md jsy. Sqf nql njsx ly vs ilusrn o gok uxwupagupaz u.
最后,下面的文本使用相同的方式进行混淆,但是还从字符串中删除了所有空格和特殊字符:
cishkclruervutzgnyarkgzjsaqgsrzvmmrzweolpcnvbkxrvdnqrlurhpmhfaxsuoqncxgz
const
OrdBigA = Ord('A');
OrdBigZ = Ord('Z');
OrdSmlA = Ord('a');
OrdSmlZ = Ord('z');
function imod(const x: integer; const y: integer): integer;
begin
if x >= 0 then
imod := x - floor(x/y) * y
else
imod := x + ceil(-x/y) * y;
end;
procedure Vigenère(var Str: string; const Key: string);
var
n, i, o: integer;
KeyChrs: TBytes;
begin
n := length(Key);
SetLength(KeyChrs, n);
for i := 1 to n do
if InRange(ord(Key[i]), OrdBigA, OrdBigZ) then
KeyChrs[i - 1] := Ord(Key[i]) - OrdBigA
else
raise Exception.Create('Invalid character in Vigenère key.');
for i := 1 to length(Str) do
begin
o := Ord(Str[i]);
if InRange(o, OrdBigA, OrdBigZ) then
Str[i] := Chr(OrdBigA + imod((o - OrdBigA + KeyChrs[(i-1) mod n]), 26))
else if InRange(o, OrdSmlA, OrdSmlZ) then
Str[i] := Chr(OrdSmlA + imod((o - OrdSmlA + KeyChrs[(i-1) mod n]), 26));
end;
end;
function Vigenèref(const Str: string; const Key: string): string;
begin
result := Str;
Vigenère(result, Key);
end;
procedure VigenèreD(var Str: string; const Key: string);
var
n, i, o: integer;
KeyChrs: TBytes;
begin
n := length(Key);
SetLength(KeyChrs, n);
for i := 1 to n do
if InRange(ord(Key[i]), OrdBigA, OrdBigZ) then
KeyChrs[i - 1] := Ord(Key[i]) - OrdBigA
else
raise Exception.Create('Invalid character in Vigenère key.');
for i := 1 to length(Str) do
begin
o := Ord(Str[i]);
if InRange(o, OrdBigA, OrdBigZ) then
Str[i] := Chr(OrdBigA + imod((o - OrdBigA - KeyChrs[(i-1) mod n]), 26))
else if InRange(o, OrdSmlA, OrdSmlZ) then
Str[i] := Chr(OrdSmlA + imod((o - OrdSmlA - KeyChrs[(i-1) mod n]), 26));
end;
end;
function VigenèreDf(const Str: string; const Key: string): string;
begin
result := Str;
VigenèreD(result, Key);
end;