首页 > 编程技术 > php

PHP与asp.net C#可共用的可逆加密算法

发布时间:2016-11-25 16:21

因为工作需我们需要在php中生成加密然后在asp.net中接受过来的密码再解密,下面我找到一个PHP与asp.net C#可共用的可逆加密算法,有需要了解的同学可参考。

php加密算法

 代码如下 复制代码

<?php
class DES
{
    var $key;
    var $iv; //偏移量
   
    function DES($key = '11001100', $iv=0 ) {
    //key长度8例如:1234abcd
        $this->key = $key;
        if( $iv == 0 ) {
            $this->iv = $key; //默认以$key 作为 iv
        } else {
            $this->iv = $iv; //mcrypt_create_iv ( mcrypt_get_block_size (MCRYPT_DES, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM );
        }
    }
   
    function encrypt($str) {
    //加密,返回大写十六进制字符串
        $size = mcrypt_get_block_size ( MCRYPT_DES, MCRYPT_MODE_CBC );
        $str = $this->pkcs5Pad ( $str, $size );
        return strtoupper( bin2hex( mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv ) ) );
    }
   
    function decrypt($str) {
    //解密
        $strBin = $this->hex2bin( strtolower( $str ) );
        $str = mcrypt_cbc( MCRYPT_DES, $this->key, $strBin, MCRYPT_DECRYPT, $this->iv );
        $str = $this->pkcs5Unpad( $str );
        return $str;
    }
   
    function hex2bin($hexData) {
        $binData = "";
        for($i = 0; $i < strlen ( $hexData ); $i += 2) {
            $binData .= chr ( hexdec ( substr ( $hexData, $i, 2 ) ) );
        }
        return $binData;
    }

    function pkcs5Pad($text, $blocksize) {
        $pad = $blocksize - (strlen ( $text ) % $blocksize);
        return $text . str_repeat ( chr ( $pad ), $pad );
    }
   
    function pkcs5Unpad($text) {
        $pad = ord ( $text {strlen ( $text ) - 1} );
        if ($pad > strlen ( $text ))
            return false;
        if (strspn ( $text, chr ( $pad ), strlen ( $text ) - $pad ) != $pad)
            return false;
        return substr ( $text, 0, - 1 * $pad );
    }
   
}
?>

asp.net程序代码

 

 代码如下 复制代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace WindowsFormsApplication1
{
    /// <summary>
    /// DES加密解密字符串
    /// </summary>
    public class DesEncryption
    {
        /// <summary>
        /// DES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串,失败返回null</returns>
        public static string EncryptDES(string encryptString, string encryptKey = "11001100")
        {
            try
            {
                byte[] rgbKey = ASCIIEncoding.ASCII.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIV = rgbKey;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                StringBuilder ret = new StringBuilder();
                foreach (byte b in mStream.ToArray())
                {
                    ret.AppendFormat("{0:X2}", b);
                }
                ret.ToString();
                return ret.ToString();
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// DES解密字符串
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
        /// <returns>解密成功返回解密后的字符串,失败返回null</returns>
        public static string DecryptDES(string decryptString, string decryptKey = "11001100")
        {
            try
            {
                byte[] rgbKey = ASCIIEncoding.ASCII.GetBytes(decryptKey);
                byte[] rgbIV = rgbKey;
                byte[] inputByteArray = new byte[decryptString.Length / 2];
                for (int x = 0; x < decryptString.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(decryptString.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }           
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return null;
            }
        }
    }
}

在php中fsockopen函数可以模仿用户去访问一些网站并且还可以带一些常用的信息,如果浏览器,IP,post,get 等等数据,下面我分别一来给大家介绍介绍。

如果你要使用fsockopen函数我们必须在php.ini中把allow_url_fopen = On 设置为开启状态。

 fsockopen() Example

 代码如下 复制代码

<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />n";
} else {
    $out = "GET / HTTP/1.1rn";
    $out .= "Host: www.example.comrn";
    $out .= "Connection: Closernrn";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}
?>


伪造post

POST HTTP请求(URL)并获取返回值

 代码如下 复制代码

<?php 

  $srv_ip = '192.168.1.5';//你的目标服务地址. 

  $srv_port = 80;//端口 

  $url = 'http://localhost/fsock.php'; //接收你post的URL具体地址  

  $fp = ''; 

  $errno = 0;//错误处理 

  $errstr = '';//错误处理 

  $timeout = 10;//多久没有连上就中断 

  $post_str = "username=demo&password=hahaha";//要提交的内容. 

  //打开网络的 Socket 链接。 

  $fp = fsockopen($srv_ip,$srv_port,$errno,$errstr,$timeout); 

  if (!$fp){ 

   echo('fp fail'); 

  } 

  $content_length = strlen($post_str); 

  $post_header = "POST $url HTTP/1.1rn"; 

  $post_header .= "Content-Type: application/x-www-form-urlencodedrn"; 

  $post_header .= "User-Agent: MSIErn"; 

  $post_header .= "Host: ".$srv_ip."rn"; 

  $post_header .= "Content-Length: ".$content_length."rn"; 

  $post_header .= "Connection: closernrn"; 

  $post_header .= $post_str."rnrn"; 

  fwrite($fp,$post_header); 

 

  $inheader = 1; 

  while(!feof($fp)){//测试文件指针是否到了文件结束的位置 

   $line = fgets($fp,1024); 

   //去掉请求包的头信息 

   if ($inheader && ($line == "n" || $line == "rn")) { 

         $inheader = 0; 

    } 

    if ($inheader == 0) { 

      echo $line; 

    } 

  } 

  fclose($fp); 

  unset ($line); 

?> 

简要说明:代码第二行是你的IP地址或域名,第四行是你要POST的页面的具体地址,本例用的是fsock.php,fsock.php内容如下:

 代码如下 复制代码

<?php 

    echo "username:".$_POST['username']."<br/>"; 

    echo "password:".$_POST['password']; 

?> 


 

结果为:

username:demo

password:hahaha


伪造get


同时伪造post,get方法。

 代码如下 复制代码

<?php
//fsocket模拟post提交
$purl = "http://localhost/netphp/test2.php?uu=rrrrrrrrrrrr";
print_r(parse_url($url));
sock_post($purl,"uu=55555555555555555");
//fsocket模拟get提交
function sock_get($url, $query)
{
   $info = parse_url($url);
   $fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
   $head = "GET ".$info['path']."?".$info["query"]." HTTP/1.0rn";
   $head .= "Host: ".$info['host']."rn";
   $head .= "rn";
   $write = fputs($fp, $head);
   while (!feof($fp))
   {
    $line = fread($fp,4096);
    echo $line;
   }
}
sock_post($purl,"uu=rrrrrrrrrrrrrrrr");
function sock_post($url, $query)
{
   $info = parse_url($url);
   $fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
   $head = "POST ".$info['path']."?".$info["query"]." HTTP/1.0rn";
   $head .= "Host: ".$info['host']."rn";
   $head .= "Referer: http://".$info['host'].$info['path']."rn";
   $head .= "Content-type: application/x-www-form-urlencodedrn";
   $head .= "Content-Length: ".strlen(trim($query))."rn";
   $head .= "rn";
   $head .= trim($query);
   $write = fputs($fp, $head);
   while (!feof($fp))
   {
    $line = fread($fp,4096);
    echo $line;
   }
}
?>

多线程是java中一个很不错的东西,很多朋友说在php中不可以使用PHP多线程了,其实那是错误的说法PHP多线程实现方法和fsockopen函数有关,下面我们来介绍具体实现程序代码,有需要了解的同学可参考。

当有人想要实现并发功能时,他们通常会想到用fork或者spawn threads,但是当他们发现php不支持多线程的时候,大概会转换思路去用一些不够好的语言,比如perl。
其实的是大多数情况下,你大可不必使用 fork 或者线程,并且你会得到比用 fork 或 thread 更好的性能。
假设你要建立一个服务来检查正在运行的n台服务器,以确定他们还在正常运转。你可能会写下面这样的代码:

 代码如下 复制代码

<?php
$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com");
$timeout = 15;
$status = array();
foreach ($hosts as $host) {
 $errno = 0;
 $errstr = "";
 $s = fsockopen($host, 80, $errno, $errstr, $timeout);
 if ($s) {
  $status[$host] = "Connectedn";
  fwrite($s, "HEAD / HTTP/1.0rnHost: $hostrnrn");
  do {
   $data = fread($s, 8192);
   if (strlen($data) == 0) {
   break;
   }
   $status[$host] .= $data;
  } while (true);
  fclose($s);
 } else {
  $status[$host] = "Connection failed: $errno $errstrn";
 }
}
print_r($status);
?>

它运行的很好,但是在fsockopen()分析完hostname并且建立一个成功的连接(或者延时$timeout秒)之前,扩充这段代码来管理大量服务器将耗费很长时间。
因此我们必须放弃这段代码;我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname(所以直接使用ip更加明智),不过将在打开一个连接之后立刻返回,继而我们就可以连接下一台服务器。
有两种方法可以实现;PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本,你需要自己动手,用sockets扩展解决问题。
下面是PHP5中的解决方法:
它运行的很好,但是在fsockopen()分析完hostname并且建立一个成功的连接(或者延时$timeout秒)之前,扩充这段代码来管理大量服务器将耗费很长时间。
因此我们必须放弃这段代码;我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname(所以直接使用ip更加明智),不过将在打开一个连接之后立刻返回,继而我们就可以连接下一台服务器。
有两种方法可以实现;PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本,你需要自己动手,用sockets扩展解决问题。
下面是PHP5中的解决方法:

 代码如下 复制代码
<?php
$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com");
$timeout = 15;
$status = array();
$sockets = array();
/* Initiate connections to all the hosts simultaneously */
foreach ($hosts as $id => $host) {
 $s = stream_socket_client("
$
$host:80", $errno, $errstr, $timeout,
  STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
 if ($s) {
  $sockets[$id] = $s;
  $status[$id] = "in progress";
 } else {
  $status[$id] = "failed, $errno $errstr";
 }
}
/* Now, wait for the results to come back in */
while (count($sockets)) {
 $read = $write = $sockets;
 /* This is the magic function - explained below */
 $n = stream_select($read, $write, $e = null, $timeout);
 if ($n > 0) {
  /* readable sockets either have data for us, or are failed
   * connection attempts */
  foreach ($read as $r) {
      $id = array_search($r, $sockets);
      $data = fread($r, 8192);
      if (strlen($data) == 0) {
   if ($status[$id] == "in progress") {
    $status[$id] = "failed to connect";
   }
   fclose($r);
   unset($sockets[$id]);
      } else {
   $status[$id] .= $data;
      }
  }
  /* writeable sockets can accept an HTTP request */
  foreach ($write as $w) {
   $id = array_search($w, $sockets);
   fwrite($w, "HEAD / HTTP/1.0rnHost: "
    . $hosts[$id] .  "rnrn");
   $status[$id] = "waiting for response";
  }
 } else {
  /* timed out waiting; assume that all hosts associated
   * with $sockets are faulty */
  foreach ($sockets as $id => $s) {
   $status[$id] = "timed out " . $status[$id];
  }
  break;
 }
}
foreach ($hosts as $id => $host) {
 echo "Host: $hostn";
 echo "Status: " . $status[$id] . "nn";
}
?>

我们用stream_select()等待sockets打开的连接事件。stream_select()调用系统的select(2)函数来工作:前面三个参数是你要使用的streams的数组;你可以对其读取,写入和获取异常(分别针对三个参数)。stream_select()可以通过设置$timeout(秒)参数来等待事件发生-事件发生时,相应的sockets数据将写入你传入的参数。
下面是PHP4.1.0之后版本的实现,如果你已经在编译PHP时包含了sockets(ext/sockets)支持,你可以使用根上面类似的代码,只是需要将上面的streams/filesystem函数的功能用ext/sockets函数实现。主要的不同在于我们用下面的函数代替stream_socket_client()来建立连接:

 代码如下 复制代码
<?php
// This value is correct for Linux, other systems have other values
define('EINPROGRESS', 115);
function non_blocking_connect($host, $port, &$errno, &$errstr, $timeout) {
 $ip = gethostbyname($host);
 $s = socket_create(AF_INET, SOCK_STREAM, 0);
 if (socket_set_nonblock($s)) {
  $r = @socket_connect($s, $ip, $port);
  if ($r || socket_last_error() == EINPROGRESS) {
   $errno = EINPROGRESS;
   return $s;
  }
 }
 $errno = socket_last_error($s);
 $errstr = socket_strerror($errno);
 socket_close($s);
 return false;
}
?>

现在用socket_select()替换掉stream_select(),用socket_read()替换掉fread(),用socket_write()替换掉fwrite(),用socket_close()替换掉fclose()就可以执行脚本了!
PHP5的先进之处在于,你可以用stream_select()处理几乎所有的stream-例如你可以通过include STDIN用它接收键盘输入并保存进数组,你还可以接收通过proc_open()打开的管道中的数据。

下面来分享一个PHP多线程类

 代码如下 复制代码

 * @title:      PHP多线程类(Thread)
 * @version:    1.0
 * @author:     phper.org.cn < web@phper.org.cn >
 * @published:  2010-11-2
 *
 * PHP多线程应用示例:
 *  require_once 'thread.class.php';
 *  $thread = new thread();
 *  $thread->addthread('action_log','a');
 *  $thread->addthread('action_log','b');
 *  $thread->addthread('action_log','c');
 *  $thread->runthread();
 * 
 *  function action_log($info) {
 *      $log = 'log/' . microtime() . '.log';
 *      $txt = $info . "rnrn" . 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn";
 *      $fp = fopen($log, 'w');
 *      fwrite($fp, $txt);
 *      fclose($fp);
 *  }
 */
class thread {
 
    var $hooks = array();
    var $args = array();
 
    function thread() {
    }
 
    function addthread($func)
    {
        $args = array_slice(func_get_args(), 1);
        $this->hooks[] = $func;
        $this->args[] = $args;
        return true;
    }
 
    function runthread()
    {
        if(isset($_GET['flag']))
        {
            $flag = intval($_GET['flag']);
        }
        if($flag || $flag === 0)
        {
            call_user_func_array($this->hooks[$flag], $this->args[$flag]);
        }
        else
        {
            for($i = 0, $size = count($this->hooks); $i < $size; $i++)
            {
                $fp=fsockopen($_SERVER['HTTP_HOST'],$_SERVER['SERVER_PORT']);
                if($fp)
                {
                    $out = "GET {$_SERVER['PHP_SELF']}?flag=$i HTTP/1.1rn";
                    $out .= "Host: {$_SERVER['HTTP_HOST']}rn";
                    $out .= "Connection: Closernrn";
                    fputs($fp,$out);
                    fclose($fp);
                }
            }
        }
    }
}

本文章来给各位同学介绍php中读取大文件实现方法详解吧,有需要了解的同学可进入参考参考。

需求如下: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容。

实现方法:

1. 直接采用file函数来操作
注: 由于 file函数是一次性将所有内容读入内存,而php为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下 限制只能最大使用内存16M,这是通过php.ini里的memory_limit = 16M来进行设置,这个值如果设置-1,则内存使用量不受限制.

下面是一段用file来取出这具文件最后一行的代码.
整个代码执行完成耗时 116.9613 (s).

 代码如下 复制代码
ini_set('memory_limit','-1');
$file = 'access.log';
$data = file($file);
$line = $data[count($data)-1];
echo $line;

我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了.

2.直接调用linux的tail命令来显示最后几行

在linux命令行下,可以直接使用tail -n 10 access.log很轻易的显示日志文件最后几行,可以直接用php来调用tail命令,执行php代码如下.
整个代码执行完成耗时 0.0034 (s)

 代码如下 复制代码
file = 'access.log';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 1 $file`;
echo $line;

3. 直接使用php的fseek来进行文件操作

这种方式是最为普遍的方式,它不需要将文件的内容全部读入内存,而是直接通过指针来操作,所以效率是相当高效的.在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法.
方法一:
首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置,再取这一行的位置,依次类推,直到找到了$num行。
实现代码如下

整个代码执行完成耗时 0.0095 (s)

 代码如下 复制代码

function tail($fp,$n,$base=5)
{
    assert($n>0);
    $pos = $n+1;
    $lines = array();
    while(count($lines)< =$n){
        try{
            fseek($fp,-$pos,SEEK_END);
        } catch (Exception $e){
            fseek(0);
            break;
        }
        $pos *= $base;
        while(!feof($fp)){
            array_unshift($lines,fgets($fp));
        }
    }
    return array_slice($lines,0,$n);
}
var_dump(tail(fopen("access.log","r+"),10));

方法二 :

还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换行符(n)的个数来判断是否已经读完最后$num行数据.
实现代码如下
整个代码执行完成耗时 0.0009(s).

 代码如下 复制代码

$fp = fopen($file, "r");
$line = 10;
$pos = -2;
$t = " ";
$data = "";
while ($line > 0) {
    while ($t != "n") {
        fseek($fp, $pos, SEEK_END);
        $t = fgetc($fp);
        $pos --;
    }
    $t = " ";
    $data .= fgets($fp);
    $line --;
}
fclose ($fp);
echo $data

方法三:

整个代码执行完成耗时 0.0003(s)

 代码如下 复制代码

$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
for ($len = 0; $len < $max; $len += $chunk) {
  $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;
    fseek($fp, ($len + $seekSize) * -1, SEEK_END);
    $readData = fread($fp, $seekSize) . $readData;
 
    if (substr_count($readData, "n") >= $num + 1) {
        preg_match("!(.*?n){".($num)."}$!", $readData, $match);
        $data = $match[0];
        break;
    }
}
fclose($fp);
echo $data;

本文章来给大家介绍淘宝客API组件升级调整方法介绍,最近淘宝客API接口升级为淘宝组件调用的接口, 略微看一下开发手,发现淘宝给淘宝组件的定义很简单,下面我来给大家介绍。

通俗的讲就是JSSDK的整合和使用。
JSSDK的官方解释:
淘宝JSSDK是基于javascript的SDK,网站通过引入一个JS文件就可以实现:
通过JSSDK提供的方法,安全、便捷的利用javascript访问Taobao API。
通过JSSDK提供的组件方法,快速、简单的集成淘宝电商组件。
对安全性较高的服务开放的唯一入口,例如:关联推荐中用户行为的关联推荐,收藏夹接口等。
合作网站无需强大的后端服务系统,通过前端获取数据并直接展示,可获取到“小投入支撑大量用户”的效果。
为合作网站提供多维度的用户数据分析服务。
php页面的JSSDK的整合
使用诸如 WordPress 这种PHP程序的网站主这次还是很有福利的,
因为官方的文档中便是用php文档整合JSSDK来举例的。
1.在页面中加载jssdk文件
其中appkey=xxxxxxx后面的xxxxx就是你的appkey

 代码如下 复制代码

<script" width=100% src="http://l.tbcdn.cn/apps/top/x/sdk.js?appkey=xxxxxxx"></script>

2.生成签名,存入cookie中

 代码如下 复制代码

<?php
$app_key = 'xxxxxxx';/*填写appkey */
$secret='';/*填入Appsecret'*/
$timestamp=time()."000";
//签名所需的字符串拼接
$message = $secret.'app_key'.$app_key.'timestamp'.$timestamp.$secret;
//获得签名
$mysign=strtoupper(hash_hmac("md5",$message,$secret));
//存入时间戳
setcookie("timestamp",$timestamp);
//存入签名
setcookie("sign",$mysign);
?>

淘宝客接口调用

这里给一个最简单的,官方调用接口的示例

 代码如下 复制代码

TOP.api('rest', 'get',{
   method:'taobao.taobaoke.widget.items.convert',
    track_iids:'19237740785_track_11116',
   fields:'num_iid,click_url,commission_rate'
 },function(resp){
   if(resp.error_response){
     alert('taobao.taobaoke.widget.items.convert接口获取商信息品失败!'+resp.error_response.msg);
      return false;
     }
     var respItem=resp.taobaoke_items.taobaoke_item;
     for(var i=0;i<respItem.length;i++){
      //$("#r"+respItem[i].num_iid).html("佣金:"+Number(respItem[i].commission_rate)/100+"%");
      //$("#a"+respItem[i].num_iid).attr("href",respItem[i].click_url);
      }
 })

标签:[!--infotagslink--]

您可能感兴趣的文章: