php的non-thread-safe和thread-safe这两个版本有何区别?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2773 次浏览 • 2017-06-25 14:45 • 来自相关话题

PHP实现RSA加密解密

zkbhj 发表了文章 • 0 个评论 • 1501 次浏览 • 2017-06-16 10:25 • 来自相关话题

class Someet
{

//加密方法 $data 加密字符串
public static function getencrypt($data){

// 公钥加密
$encrypt_data = '';
//获取公钥
$pubkey = openssl_pkey_get_public(file_get_contents('someet_pub.key'));
openssl_public_encrypt($data, $encrypt_data, $pubkey);
$encrypt_data = base64_encode($encrypt_data);
return $encrypt_data;

}


//解密方法 $encrypt_data 获取的加密后的字符串
public static function getdecrypt($encrypt_data)
{
//把解密的字符串里的,空格转换为+号
$encrypt_data = str_replace(' ','+', $encrypt_data);
// 私钥解密
$prikey = openssl_pkey_get_private(file_get_contents('someet.key'));
$encrypt_data = base64_decode($encrypt_data);
openssl_private_decrypt($encrypt_data, $decrypt_data, $prikey);
return $decrypt_data;
}


}

//使用
$sommet = new Someet();
//加密
$encrypt = $sommet->getencrypt($encryptkey);
//解密
$decrypt = $sommet->getdecrypt($decryptkey);


RSA的加密解密,对加密串的格式要求非常严格,不同语言,像Java,.net 加密输出的串,到达php页面,会出现加号被转成空格的情况,因为php get 会默认执行一遍 urldecode, 而urldecode 会把加号转为空格,从而导致整个加密串发生了变化,所以解密不出来。
生成公钥、私钥对,私钥加密的内容能通过公钥解密(反过来亦可以)

下载开源RSA密钥生成工具openssl(通常Linux系统都自带该程序),解压缩至独立的文件夹,进入其中的bin目录,执行以下命令:openssl genrsa -out rsa_private_key.pem 1024
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
第一条命令生成原始 RSA私钥文件 rsa_private_key.pem,第二条命令将原始 RSA私钥转换为 pkcs8格式,第三条生成RSA公钥 rsa_public_key.pem
从上面看出通过私钥能生成对应的公钥,因此我们将私钥private_key.pem用在服务器端,公钥发放给Android跟iOS等前端。 查看全部

timg_(1).jpg
class Someet
{

//加密方法 $data 加密字符串
public static function getencrypt($data){

// 公钥加密
$encrypt_data = '';
//获取公钥
$pubkey = openssl_pkey_get_public(file_get_contents('someet_pub.key'));
openssl_public_encrypt($data, $encrypt_data, $pubkey);
$encrypt_data = base64_encode($encrypt_data);
return $encrypt_data;

}


//解密方法 $encrypt_data 获取的加密后的字符串
public static function getdecrypt($encrypt_data)
{
//把解密的字符串里的,空格转换为+号
$encrypt_data = str_replace(' ','+', $encrypt_data);
// 私钥解密
$prikey = openssl_pkey_get_private(file_get_contents('someet.key'));
$encrypt_data = base64_decode($encrypt_data);
openssl_private_decrypt($encrypt_data, $decrypt_data, $prikey);
return $decrypt_data;
}


}

//使用
$sommet = new Someet();
//加密
$encrypt = $sommet->getencrypt($encryptkey);
//解密
$decrypt = $sommet->getdecrypt($decryptkey);


RSA的加密解密,对加密串的格式要求非常严格,不同语言,像Java,.net 加密输出的串,到达php页面,会出现加号被转成空格的情况,因为php get 会默认执行一遍 urldecode, 而urldecode 会把加号转为空格,从而导致整个加密串发生了变化,所以解密不出来。
生成公钥、私钥对,私钥加密的内容能通过公钥解密(反过来亦可以)

下载开源RSA密钥生成工具openssl(通常Linux系统都自带该程序),解压缩至独立的文件夹,进入其中的bin目录,执行以下命令:
openssl genrsa -out rsa_private_key.pem 1024
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

第一条命令生成原始 RSA私钥文件 rsa_private_key.pem,第二条命令将原始 RSA私钥转换为 pkcs8格式,第三条生成RSA公钥 rsa_public_key.pem
从上面看出通过私钥能生成对应的公钥,因此我们将私钥private_key.pem用在服务器端,公钥发放给Android跟iOS等前端。

PHP 获取html中某个div中内容的方法是什么?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 4868 次浏览 • 2017-06-08 17:16 • 来自相关话题

2017年PHP程序员未来路在何方?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2403 次浏览 • 2017-06-08 16:35 • 来自相关话题

PHP为什么不建议使用eval()函数?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 3576 次浏览 • 2017-06-07 18:30 • 来自相关话题

php中$_ENV与$_SERVER有啥区别?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 4757 次浏览 • 2017-06-06 17:44 • 来自相关话题

数据库里的冗余字段相关问题

zkbhj 发表了文章 • 0 个评论 • 1378 次浏览 • 2017-06-05 15:36 • 来自相关话题

数据库里的冗余字段一定要记得随时保持更新,跨表操作要有事务。
数据库里的冗余字段一定要记得随时保持更新,跨表操作要有事务。

如何生成全局唯一ID并能大致有序?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 3683 次浏览 • 2017-06-02 10:43 • 来自相关话题

PHP json_encode 转换成空对象和空数组如何指定?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 5522 次浏览 • 2017-06-01 16:14 • 来自相关话题

记录接口中常见的简单内容加密方式:恺撒加密的PHP实现

zkbhj 发表了文章 • 0 个评论 • 1618 次浏览 • 2017-05-23 16:17 • 来自相关话题

问题描述:
    凯撒密码是把字母表中的每个字母用该字母后的某个字母进行代替。
    凯撒密码的通用加密算法是:C=E(P)=(P+k) mod 260<k<26。
    凯撒密码的通用解密算法是:P=D(C)=(P-k) mod 260<k<26。

基本要求:
    实现凯撒密码的加密、解密算法,能够根据用户选择秘钥(移位数)和明文进行加解密。

实现提示:
    (1) 用户可以通过命令实现密钥和明文的选择;
    (2) 由于字母表中共有26个字符,因此,移位前应先将移动的位数(key)和26取模。
    (3) 尽管移位前已经将移动的位数和26取模,但是通过这种方式实现的右移和左移仍可能发生超界。因此,移位后仍要判断是否超界。
 一段Python代码:
#License:GPL v3 or higher.
#Copyright (C) 2012 Biergaizi

import sys
times=0
plain=input("Please input your plain text: ")
value=input("Please input your key(included negatives): ")
secret_list=list(plain)
secret_list_len=len(secret_list)

try:
value=int(value)
except ValueError:
print("Please input an integer.")
sys.exit()


#a的ANSI码是97, z的ANSI码是122。
#A的ANSI码是65, Z的ANSI码是90。

print("")
print("secret: ",end='')

while times < secret_list_len:
times=times+1
#ansi_raw即没有经过任何处理的原始ANSI。
ansi_raw=ord(secret_list[0+times-1])

#ansi是经过移位加密的ANSI。
ansi=ansi_raw+int(value)

#word是用户输入的原始字符。
word=(secret_list[0+times-1])

#如果ansi_raw小于65或大于90,而且还不是小写字母,那么则说明它根本就不是字母。不加密,直接输出原始内容。
if (ansi_raw < 65 or ansi_raw > 90) and word.islower() == False :
print(word,end='')

#如果ansi_raw小于97或大于122,而且还不是大写字母,那么则说明它根本不是字母。不加密,直接输出原始内容。
elif (ansi_raw < 97 or ansi_raw > 122) and word.isupper() == False:
print(word,end='')

#否则,它就是字母。
else:
#如果它是大写字母,而且ANSI码大于90,则说明向后出界。那么通过这个公式回到开头,直到不出界为止。
while word.isupper() == True and ansi > 90:
ansi = -26 + ansi

#如果它是大写字母,而且ANSI码小于65,则说明向前出界。那么通过这个公式回到结尾,直到不出界为止。
while word.isupper() == True and ansi < 65:
ansi = 26 + ansi

#如果它是小写字母,而且ANSI码大于122,则说明向后出界。那么通过这个公式回到开头,直到不出界为止。
while word.isupper() == False and ansi > 122:
ansi = -26 + ansi

#如果它是小写字母,而且ANSI码小于97,则说明向前出界。那么通过这个公式回到结尾,直到不出界为止。
while word.isupper() == False and ansi < 97:
ansi = 26 + ansi

#将处理过的ANSI转换为字符,来输出密文。
print(chr(ansi),end='')

print("")
思路:
①加密的整体思路是不是字母的数字不进行加密,若是小写字母,对字母移位(ASCII + 秘钥)后若ASCII码小于97或大于122则表示字母越界,只需要加26或减26直到移位后的在小写字母的范围内即可;同理大写字母也是相同的过程;
②解密的整体思路只需将移位后的的字母还原(ASCII - 秘钥),其他步骤和加密一样。

有了思路接下来写PHP代码:
<?php
class Caesar{

private $simple;//明文
private $secretKey;//秘钥
private $ciphertext;//密文
private $opResult;//加密或解密后的结果
private $operatorType;//操作类型;0代表加密1:代表解密

/**
* __construct 构造函数初始化类属性
* @param String $input 输入字符内容
* @param integer $secretKey 秘钥
* @param integer $operatorType 操作类型;0代表加密1:代表解密
*/
public function __construct($input,$secretKey = 1,$operatorType = 0){

$this->operatorType = intval($operatorType);
if($this->operatorType == 0){
$this->simple = $input;
$this->ciphertext = "";
}elseif ($this->operatorType == 1) {
$this->ciphertext = $input;
$this->simple = "";
}else{
echo "please input right operatorType";
exit();
}
$this->opResult = "";
$this->secretKey = intval($secretKey);
}


/**
* crypto 解密或加密函数
* @return String 加解密后的结果
*/
public function crypto(){

//获取加密解密后的字符串
$charArray = ($this->operatorType==0) ? str_split ($this->simple) : str_split ($this->ciphertext);

//遍历整个字符数组进行加密解密操作
foreach ($charArray as $key => $value) {
$asciiOriginal = ord($value);//字符的ASCII值
$asciiTransfrom =($this->operatorType==0) ? $asciiOriginal+$this->secretKey : $asciiOriginal-$this->secretKey;//加解密后的ASCII的值

//值得注意的是||的优先级比&&的优先级低,若不加括号会造成问题;
//若不是大写字母并且$asciiOriginal的值小于65或大于90则不加密
if ( ($asciiOriginal<65 || $asciiOriginal > 90 ) && ($this->isLowerCase($value)==false)) {
$this->opResult .= $value;

//若不是大写字母并且$asciiOriginal的值小于97或大于122则不加密
}elseif ( ($asciiOriginal<97 || $asciiOriginal > 122) &&($this->isCapital($value)==false)) {
$this->opResult .= $value;
}else{

//循环处理越界的问题
while ($asciiTransfrom<65&&$this->isCapital($value)) {
$asciiTransfrom += 26;
}

while ($asciiTransfrom>90&&$this->isCapital($value)) {
$asciiTransfrom -= 26;
}

while ($asciiTransfrom<97&&$this->isLowerCase($value)) {
$asciiTransfrom += 26;
}

while ($asciiTransfrom>122&&$this->isLowerCase($value)) {
$asciiTransfrom -= 26;
}
}
$this->opResult .= chr($asciiTransfrom);
}
return $this->opResult;
}

/**
* isLowerCase 判断是否为小写字母
* @param char $char 传入的字符
* @return boolean 返回boolean类型
*/
private function isLowerCase($char){
if(preg_match("/^[a-z]+$/", $char)){
return true;
}else{
return false;
}
}

/**
* isCapital 判断是否为小写字母
* @param char $char 传入的字符
* @return boolean 返回boolean类型
*/
private function isCapital($char){
if(preg_match("/^[A-Z]+$/", $char)){
return true;
}else{
return false;
}
}

}

$string = $_SERVER['argv'][1];
if (!$string) {
echo "please input parameter";
}
$test = new Caesar($string,1,1);
echo $test->crypto();
?>
  查看全部
问题描述:
    凯撒密码是把字母表中的每个字母用该字母后的某个字母进行代替。
    凯撒密码的通用加密算法是:C=E(P)=(P+k) mod 260<k<26。
    凯撒密码的通用解密算法是:P=D(C)=(P-k) mod 260<k<26。

基本要求:
    实现凯撒密码的加密、解密算法,能够根据用户选择秘钥(移位数)和明文进行加解密。

实现提示:
    (1) 用户可以通过命令实现密钥和明文的选择;
    (2) 由于字母表中共有26个字符,因此,移位前应先将移动的位数(key)和26取模。
    (3) 尽管移位前已经将移动的位数和26取模,但是通过这种方式实现的右移和左移仍可能发生超界。因此,移位后仍要判断是否超界。
 一段Python代码:
#License:GPL v3 or higher.
#Copyright (C) 2012 Biergaizi

import sys
times=0
plain=input("Please input your plain text: ")
value=input("Please input your key(included negatives): ")
secret_list=list(plain)
secret_list_len=len(secret_list)

try:
value=int(value)
except ValueError:
print("Please input an integer.")
sys.exit()


#a的ANSI码是97, z的ANSI码是122。
#A的ANSI码是65, Z的ANSI码是90。

print("")
print("secret: ",end='')

while times < secret_list_len:
times=times+1
#ansi_raw即没有经过任何处理的原始ANSI。
ansi_raw=ord(secret_list[0+times-1])

#ansi是经过移位加密的ANSI。
ansi=ansi_raw+int(value)

#word是用户输入的原始字符。
word=(secret_list[0+times-1])

#如果ansi_raw小于65或大于90,而且还不是小写字母,那么则说明它根本就不是字母。不加密,直接输出原始内容。
if (ansi_raw < 65 or ansi_raw > 90) and word.islower() == False :
print(word,end='')

#如果ansi_raw小于97或大于122,而且还不是大写字母,那么则说明它根本不是字母。不加密,直接输出原始内容。
elif (ansi_raw < 97 or ansi_raw > 122) and word.isupper() == False:
print(word,end='')

#否则,它就是字母。
else:
#如果它是大写字母,而且ANSI码大于90,则说明向后出界。那么通过这个公式回到开头,直到不出界为止。
while word.isupper() == True and ansi > 90:
ansi = -26 + ansi

#如果它是大写字母,而且ANSI码小于65,则说明向前出界。那么通过这个公式回到结尾,直到不出界为止。
while word.isupper() == True and ansi < 65:
ansi = 26 + ansi

#如果它是小写字母,而且ANSI码大于122,则说明向后出界。那么通过这个公式回到开头,直到不出界为止。
while word.isupper() == False and ansi > 122:
ansi = -26 + ansi

#如果它是小写字母,而且ANSI码小于97,则说明向前出界。那么通过这个公式回到结尾,直到不出界为止。
while word.isupper() == False and ansi < 97:
ansi = 26 + ansi

#将处理过的ANSI转换为字符,来输出密文。
print(chr(ansi),end='')

print("")

思路:
①加密的整体思路是不是字母的数字不进行加密,若是小写字母,对字母移位(ASCII + 秘钥)后若ASCII码小于97或大于122则表示字母越界,只需要加26或减26直到移位后的在小写字母的范围内即可;同理大写字母也是相同的过程;
②解密的整体思路只需将移位后的的字母还原(ASCII - 秘钥),其他步骤和加密一样。

有了思路接下来写PHP代码:
<?php
class Caesar{

private $simple;//明文
private $secretKey;//秘钥
private $ciphertext;//密文
private $opResult;//加密或解密后的结果
private $operatorType;//操作类型;0代表加密1:代表解密

/**
* __construct 构造函数初始化类属性
* @param String $input 输入字符内容
* @param integer $secretKey 秘钥
* @param integer $operatorType 操作类型;0代表加密1:代表解密
*/
public function __construct($input,$secretKey = 1,$operatorType = 0){

$this->operatorType = intval($operatorType);
if($this->operatorType == 0){
$this->simple = $input;
$this->ciphertext = "";
}elseif ($this->operatorType == 1) {
$this->ciphertext = $input;
$this->simple = "";
}else{
echo "please input right operatorType";
exit();
}
$this->opResult = "";
$this->secretKey = intval($secretKey);
}


/**
* crypto 解密或加密函数
* @return String 加解密后的结果
*/
public function crypto(){

//获取加密解密后的字符串
$charArray = ($this->operatorType==0) ? str_split ($this->simple) : str_split ($this->ciphertext);

//遍历整个字符数组进行加密解密操作
foreach ($charArray as $key => $value) {
$asciiOriginal = ord($value);//字符的ASCII值
$asciiTransfrom =($this->operatorType==0) ? $asciiOriginal+$this->secretKey : $asciiOriginal-$this->secretKey;//加解密后的ASCII的值

//值得注意的是||的优先级比&&的优先级低,若不加括号会造成问题;
//若不是大写字母并且$asciiOriginal的值小于65或大于90则不加密
if ( ($asciiOriginal<65 || $asciiOriginal > 90 ) && ($this->isLowerCase($value)==false)) {
$this->opResult .= $value;

//若不是大写字母并且$asciiOriginal的值小于97或大于122则不加密
}elseif ( ($asciiOriginal<97 || $asciiOriginal > 122) &&($this->isCapital($value)==false)) {
$this->opResult .= $value;
}else{

//循环处理越界的问题
while ($asciiTransfrom<65&&$this->isCapital($value)) {
$asciiTransfrom += 26;
}

while ($asciiTransfrom>90&&$this->isCapital($value)) {
$asciiTransfrom -= 26;
}

while ($asciiTransfrom<97&&$this->isLowerCase($value)) {
$asciiTransfrom += 26;
}

while ($asciiTransfrom>122&&$this->isLowerCase($value)) {
$asciiTransfrom -= 26;
}
}
$this->opResult .= chr($asciiTransfrom);
}
return $this->opResult;
}

/**
* isLowerCase 判断是否为小写字母
* @param char $char 传入的字符
* @return boolean 返回boolean类型
*/
private function isLowerCase($char){
if(preg_match("/^[a-z]+$/", $char)){
return true;
}else{
return false;
}
}

/**
* isCapital 判断是否为小写字母
* @param char $char 传入的字符
* @return boolean 返回boolean类型
*/
private function isCapital($char){
if(preg_match("/^[A-Z]+$/", $char)){
return true;
}else{
return false;
}
}

}

$string = $_SERVER['argv'][1];
if (!$string) {
echo "please input parameter";
}
$test = new Caesar($string,1,1);
echo $test->crypto();
?>