我需要在XE6 Firemonkey项目中加密字符串。
我尝试过dcpcrypt,但Firemonkey不支持AnciString,.....
我找到了一个适用于Firemonkey的解决方案。 我的问题是将此代码转换为PHP。
DELPHI DEMO PROJECT:Link
DELPHI CODE:
const
Codes64 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/';
function GeneratePWDSecutityString: string;
var
i, x: integer;
s1, s2: string;
begin
s1 := Codes64;
s2 := '';
for i := 0 to 15 do
begin
x := Random(Length(s1));
x := Length(s1) - x;
s2 := s2 + s1[x];
s1 := Copy(s1, 1,x - 1) + Copy(s1, x + 1,Length(s1));
end;
Result := s2;
end;
function MakeRNDString(Chars: string; Count: Integer): string;
var
i, x: integer;
begin
Result := '';
for i := 0 to Count - 1 do
begin
x := Length(chars) - Random(Length(chars));
Result := Result + chars[x];
chars := Copy(chars, 1,x - 1) + Copy(chars, x + 1,Length(chars));
end;
end;
function EncodePWDEx(Data, SecurityString: string; MinV: Integer = 0;
MaxV: Integer = 5): string;
var
i, x: integer;
s1, s2, ss: string;
begin
if minV > MaxV then
begin
i := minv;
minv := maxv;
maxv := i;
end;
if MinV < 0 then MinV := 0;
if MaxV > 100 then MaxV := 100;
Result := '';
if Length(SecurityString) < 16 then Exit;
for i := 1 to Length(SecurityString) do
begin
s1 := Copy(SecurityString, i + 1,Length(securitystring));
if Pos(SecurityString[i], s1) > 0 then Exit;
if Pos(SecurityString[i], Codes64) <= 0 then Exit;
end;
s1 := Codes64;
s2 := '';
for i := 1 to Length(SecurityString) do
begin
x := Pos(SecurityString[i], s1);
if x > 0 then s1 := Copy(s1, 1,x - 1) + Copy(s1, x + 1,Length(s1));
end;
ss := securitystring;
for i := 1 to Length(Data) do
begin
s2 := s2 + ss[Ord(Data[i]) mod 16 + 1];
ss := Copy(ss, Length(ss), 1) + Copy(ss, 1,Length(ss) - 1);
s2 := s2 + ss[Ord(Data[i]) div 16 + 1];
ss := Copy(ss, Length(ss), 1) + Copy(ss, 1,Length(ss) - 1);
end;
Result := MakeRNDString(s1, Random(MaxV - MinV) + minV + 1);
for i := 1 to Length(s2) do Result := Result + s2[i] + MakeRNDString(s1,
Random(MaxV - MinV) + minV);
end;
function DecodePWDEx(Data, SecurityString: string): string;
var
i, x, x2: integer;
s1, s2, ss: string;
begin
Result := #1;
if Length(SecurityString) < 16 then Exit;
for i := 1 to Length(SecurityString) do
begin
s1 := Copy(SecurityString, i + 1,Length(securitystring));
if Pos(SecurityString[i], s1) > 0 then Exit;
if Pos(SecurityString[i], Codes64) <= 0 then Exit;
end;
s1 := Codes64;
s2 := '';
ss := securitystring;
for i := 1 to Length(Data) do if Pos(Data[i], ss) > 0 then s2 := s2 + Data[i];
Data := s2;
s2 := '';
if Length(Data) mod 2 <> 0 then Exit;
for i := 0 to Length(Data) div 2 - 1 do
begin
x := Pos(Data[i * 2 + 1], ss) - 1;
if x < 0 then Exit;
ss := Copy(ss, Length(ss), 1) + Copy(ss, 1,Length(ss) - 1);
x2 := Pos(Data[i * 2 + 2], ss) - 1;
if x2 < 0 then Exit;
x := x + x2 * 16;
s2 := s2 + chr(x);
ss := Copy(ss, Length(ss), 1) + Copy(ss, 1,Length(ss) - 1);
end;
Result := s2;
end;
这是我的PHP代码;
function INDEX($CHAR) {
$Codes64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
return strpos($Codes64, $CHAR) + 1;
}
function MakeRNDString($Chars, $Count) {
$i = 0;
$x = 0;
$Result = '';
for ($i = 0; $i < $Count; $i++) {
$x = strlen($Chars) - rand(0, intval(strlen($Chars)));
$Result .= substr($Chars,$x,1);
$chars = substr($Chars, 1, $x - 1) + substr($Chars, $x + 1, strlen($Chars));
}
return $Result;
}
function DIV($N, $D) {
return (integer)($N / $D);
}
function EncodePWDEx($Data, $SecurityString, $minV = 0, $maxV = 5) {
$Codes64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
$i = 0;
$x = 0;
$s1 = '';
$s2 = '';
$ss = '';
if ($minV > $maxV) {
$i = $minv;
$minv = $maxv;
$maxv = $i;
}
if ($maxV < 0) {
$minV = 0;
};
if ($maxV > 100) {
$maxV = 100;
};
if (strlen($SecurityString) < 16)
Exit ;
for ($i = 0; $i < strlen($SecurityString) - 1; $i++) {
$s1 = substr($SecurityString, $i + 1, strlen($SecurityString));
if (strpos($s1, $SecurityString[$i]) > 0)
Exit ;
if (INDEX($SecurityString[$i]) <= 0)
Exit ;
}
$s1 = $Codes64;
$s2 = '';
for ($i = 0; $i < strlen($SecurityString); $i++) {
$vx = INDEX($SecurityString[$i]);
if ($vx > 0) {
$s1 = substr($s1, 1, $vx - 1) . substr($s1, $vx + 1, strlen($s1));
}
}
$ss = $SecurityString;
for ($i = 0; $i < strlen($Data); $i++) {
$FM = fmod(ord($Data[$i]), 16);
$CH = substr($ss, $FM, 1);
$s2 = $s2 . $CH;
$ss = substr($ss, strlen($ss) - 1, 1) . substr($ss, 0, strlen($ss) - 1);
$tmp = substr($ss, DIV(ord($Data[$i]), 16), 1);
$s2 = $s2 . substr($ss, DIV(ord($Data[$i]), 16), 1);
$ss = substr($ss, strlen($ss) - 1, 1) . substr($ss, 0, strlen($ss) - 1);
}
$MRN = MakeRNDString($s1, (rand(1, $maxV - $minV) + intval($minV)));
$Result = '';
$Result = $MRN;
for ($i = 0; $i < strlen($s2); $i++) {
$Result .= substr($s2,$i,1) . MakeRNDString($s1, rand(0, $maxV - $minV) + intval($minV) );
}
return $Result;
}
function DecodePWDEx($Data, $SecurityString){
$Codes64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
$Result = '';
if (strlen($SecurityString) < 16)
Exit;
for ($i = 0; $i < strlen($SecurityString) - 1; $i++) {
$s1 = substr($SecurityString, $i + 1, strlen($SecurityString));
if (strpos($s1, $SecurityString[i]) > 0 )
Exit;
if (strpos($Codes64, $SecurityString[i]) <= 0)
Exit;
}
$s1 = $Codes64;
$s2 = '';
$ss = $SecurityString;
for ($i = 0; $i < strlen($Data); $i++) {
if (strpos($ss, substr($Data,$i,1)) > 0)
$s2 = $s2 + substr($Data,$i,1);
}
$Data = $s2;
$s2 = '';
/*
if strlen($Data) mod 2 <> 0 then
Exit;
*/
$x = -1;
for ($i = 0; $i < (DIV(Length($Data), 2)); $i++) {
$x = strpos($ss,substr($Data, (i * 2),1)) - 1;
if ($x < 0)
Exit;
$ss = substr($ss, strlen($ss), 1) + substr($ss, 1, strlen($ss) - 1);
$x2 = -1;
$x2 = strpos(substr($Dat,($i * 2 + 2), 1), $ss) - 1;
if ($x2 < 0)
Exit;
$x = $x + $x2 * 16;
$s2 .= chr(x);
$ss = substr($ss, strlen($ss), 1) + substr($ss, 1, strlen($ss));
}
$Result = $s2;
return $Result;
}
$e1 = "test";
$e2 = "0/nCXpmMP2iFvJ3G";
echo '<br />Text : ' . $e1;
echo '<br />Pass : ' . $e2;
echo '<br />EncodePWDEx : <b>' . EncodePWDEx($e1, $e2).'</b>';
答案 0 :(得分:1)
在php中执行代码并不完全正确。
if (strpos($s1, $SecurityString[$i]) > 0)
php函数strpos
可能会0
返回。要测试在另一个字符串中找到的字符,您应该使用=== true
或=== false
。
if (strpos($s1, $SecurityString[$i]) === true) Exit;
if (strpos($Codes64, $SecurityString[$i]) === false) Exit;
不是
if (strpos($s1, $SecurityString[$i]) > 0) Exit;
if (INDEX($SecurityString[$i]) <= 0) Exit;
INDEX()函数错误。
function INDEX($CHAR) {
...
return strpos($Codes64, $CHAR) + 1;
}
可能会返回false + 1
!!!
你用
if (INDEX($SecurityString[$i]) <= 0) Exit;
永远不会是<= 0
!!
Code Delphi的一部分OK:
for i := 1 to Length(SecurityString) do
begin
s1 := Copy(SecurityString, i + 1,Length(securitystring));
if Pos(SecurityString[i], s1) > 0 then Exit;
if Pos(SecurityString[i], Codes64) <= 0 then Exit;
end;
部分错误的Code Php:
for ($i = 0; $i < strlen($SecurityString) - 1; $i++) {
$s1 = substr($SecurityString, $i + 1, strlen($SecurityString));
if (strpos($s1, $SecurityString[$i]) > 0)
Exit ;
if (INDEX($SecurityString[$i]) <= 0)
Exit ;
}
用Delphi OK
s1 := Codes64;
s2 := '';
for i := 1 to Length(SecurityString) do
begin
x := Pos(SecurityString[i], s1);
if x > 0 then s1 := Copy(s1, 1,x - 1) + Copy(s1, x + 1,Length(s1));
end;
PHP代码错误
for ($i = 0; $i < strlen($SecurityString); $i++) {
$vx = INDEX($SecurityString[$i]);
if ($vx > 0) { // $vx will always > 0
$s1 = substr($s1, 1, $vx - 1) . substr($s1, $vx + 1, strlen($s1));
}
}
看看
$s1 = substr($s1, 1, $vx - 1) . substr($s1, $vx + 1, strlen($s1));
substr()函数使用1
作为起点应使用0
否则总是删除两个字符而不只是一个。
$s1 = substr($s1, 1, $vx - 1)
将为我们提供一个空子字符串:$s1 = substr($s1, 1, 0);
现在$s1 == ''
更多错误
$Codes64
$s1
字符串。 $ s2。= chr(x);
$ s2。= chr($ x);
$ SecurityString ==&#39; 0 / nCXpmMP2iFvJ3G&#39;
看看下一个$SecurityString
字符。它是/
这是字符串$Codes64
中的最后一个字符。
与
$vx = INDEX($SecurityString[$i]);
我们得到位置63 + 1 == 64的Char /
现在$vx == 64
$ vx值落后于长度($ Codes64)[0..63]
从01
删除前两个字符$s1
后,字符/
位于62
位置,因此$ vx也位于长度($ s1)之后
工作Php代码
<强> EncodePWDEx 强>
取代
if (strlen($SecurityString) < 16)
Exit ;
for ($i = 0; $i < strlen($SecurityString) - 1; $i++) {
$s1 = substr($SecurityString, $i + 1, strlen($SecurityString));
if (strpos($s1, $SecurityString[$i]) > 0)
Exit ;
if (INDEX($SecurityString[$i]) <= 0)
Exit ;
}
$s1 = $Codes64;
$s2 = '';
for ($i = 0; $i < strlen($SecurityString); $i++) {
$vx = INDEX($SecurityString[$i]);
if ($vx > 0) {
$s1 = substr($s1, 1, $vx - 1) . substr($s1, $vx + 1, strlen($s1));
}
}
与
if (strlen($SecurityString) < 16)
Exit ;
for ($i = 0; $i < strlen($SecurityString) - 1; $i++) {
$s1 = substr($SecurityString, $i + 1);
if (strpos($s1, $SecurityString[$i]) !== FALSE )
Exit;
if (strpos($Codes64, $SecurityString[$i]) === FALSE)
Exit;
}
$s1 = $Codes64;
$s2 = '';
for ($i = 0; $i < strlen($SecurityString); $i++) {
$vx = strpos($s1,$SecurityString[$i]);
if ($vx !== false) {
$s1 = substr_replace ( $s1, '' , $vx , 1 );
}
}
MakeRNDString 取代
$Result .= substr($Chars,$x,1);
$chars = substr($Chars, 1, $x - 1) + substr($Chars, $x + 1, strlen($Chars));
与
$Result .= substr($Chars,$x,1);
$Chars = substr($Chars, 0, $x - 1) . substr($Chars, $x + 1);
<强> DecodePWDEx 强> 取代
for ($i = 0; $i < strlen($SecurityString) - 1; $i++) {
$s1 = substr($SecurityString, $i + 1, strlen($SecurityString));
if (strpos($s1, $SecurityString[i]) > 0 )
Exit;
if (strpos($Codes64, $SecurityString[i]) <= 0)
Exit;
}
$s1 = $Codes64;
$s2 = '';
$ss = $SecurityString;
for ($i = 0; $i < strlen($Data); $i++) {
if (strpos($ss, substr($Data,$i,1)) > 0)
$s2 = $s2 + substr($Data,$i,1);
}
$Data = $s2;
$s2 = '';
/*
if strlen($Data) mod 2 <> 0 then
Exit;
*/
$x = -1;
for ($i = 0; $i < (DIV(Length($Data), 2)); $i++) {
$x = strpos($ss,substr($Data, (i * 2),1)) - 1;
if ($x < 0)
Exit;
$ss = substr($ss, strlen($ss), 1) + substr($ss, 1, strlen($ss) - 1);
$x2 = -1;
$x2 = strpos(substr($Dat,($i * 2 + 2), 1), $ss) - 1;
if ($x2 < 0)
Exit;
$x = $x + $x2 * 16;
$s2 .= chr(x);
$ss = substr($ss, strlen($ss), 1) + substr($ss, 1, strlen($ss));
}
$Result = $s2;
return $Result;
}
与
for ($i = 0; $i < strlen($SecurityString) - 1; $i++) {
$s1 = substr($SecurityString, $i + 1);
if (strpos($s1, $SecurityString[$i]) !== FALSE )
Exit;
if (strpos($Codes64, $SecurityString[$i]) === FALSE)
Exit;
}
$s2 = '';
$ss = $SecurityString;
for ($i = 0; $i < strlen($Data); $i++) {
$fd = substr($Data,$i,1);
$vx = strpos($ss,$fd);
if ($vx !== false) {
$s2 .= $fd;
}
}
$Data = $s2;
$s2 = '';
for ($i = 0; $i < (DIV(strlen($Data), 2)); $i++) {
$x = strpos($ss,substr($Data, ($i * 2),1));
if ($x < 0) Exit;
$ss = substr($ss, strlen($ss)-1, 1) . substr($ss, 0, strlen($ss) - 1);
$fd = substr($Data,($i * 2 + 2-1), 1);
$x2 = strpos($ss,$fd);
if ($x2 < 0) Exit;
$x = $x + $x2 * 16;
$s2 .= chr($x);
$ss = substr($ss, strlen($ss)-1, 1) . substr($ss, 0, strlen($ss)-1);
}
return $s2;
}
<强>更新强>
包括当前解决方案,16 * 16 = 256个字符。您必须增加密码中的字符以放大可显示的字符。
46 x 16 == 736个字符。