数据加密技术

目录:
数据加密技术有哪些分类
每个分类的实现方式和常见算法
正文:
一、数据加密技术有哪些分类
对称加密算法
非对称加密算法
单向加密(散列算法)
散列算法不是加密算法, 因为如果目的是加密,必须满足的一个条件是加密过后可以解密。但是散列算法是无法从结果还原出原始数据的。
二、每个分类的实现方式和常见算法
对称加密算法
1、定义:
对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在大部分对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
在PHP中也有封装好的对称加密函数:Urlencode/Urldecode base64_encode()/base64_decode()
严格的来说,这两个函数其实不算是加密,更像是一种格式的序列化。
2、常见的加密算法:
DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;据说是要取代DES

3、DES算法:
对称加密算法中最经典的算法莫过于DES加密算法。DES加密采用的是分组加密的方法,使用56位密钥加密64位明文,最后产生64位密文。DES算法的基本流程如下图所示。

现在对图的整个流程做简要的分析。DES对64位的明文分组M进行操作,M经过一个初始置换IP置换成m0,将m0明文分成左半部分和右半部分m0=(L0,R0),各32位长。然后进行16轮完全相同的运算,这些运算称为函数f,在运算过程中,数据与密匙结合。经过16轮运算之后,可以看到第16轮运算,将右侧第15轮运算的结果(R15)作为左侧运算的最终结果(L16),而右侧最后的结果(R16)为左侧第15轮运算结果(L15)和函数f运算结果的异或运算所得。此后,再将左、右部分合在一起经过一个逆置换,输出密文。
实际加密过程要分成两个同时进行的过程,即加密过程和密钥生成过程,如下图所示。

如上图所示,在16轮循环的每一轮中,密匙位移位,然后再从密匙的64位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作替代成新的32位数据,在将其置换一次。这四步运算构成了图1中的函数f。然后,通过另一个异或运算,函数f的输出与左半部分结合,其结果成为新的右半部分,原来的右半部分成为新的左半部分。该操作重复16次。
DES算法的解密过程和加密过程几乎完全相同,只是使用密钥的顺序相反。

4、优缺点
优点:算法公开、加密解密的速度比较快,适合数据比较长时的使用。
缺点:
1、加密方和解密方使用同一个密钥,安全性得不到保障。
2、密钥传输的过程不安全,且容易被破解,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。

非对称加密算法
1、定义:
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
2、常见的加密算法:
RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;
DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);
ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。

3、http://www.cnblogs.com/zfxJava/p/5295957.html理解公钥和私钥(划重点)

4、优缺点
优点:对称加密算法不能实现签名,因此签名只能非对称算法。比对称加密算法更加安全。
缺点:
1、由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。
2、公钥传输的过程不安全,易被窃取和替换,由此产生了数字证书。

单向加密(散列算法)
1、定义:
属于摘要算法(哈希/散列算法),不是一种加密算法,作用是把任意长的输入字符串变化成固定长的输出串的一种函数。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同散列结果的两条信息。具有这些特性的散列结果就可以用于验证信息是否被修改。
2、常见的散列算法:
1、MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文。
2、SHA(Secure Hash Algorithm):可以对任意长度的数据运算生成一个160位的数值;

3、MD5加密注意点:

md5()为单向加密,没有逆向解密算法,但是还是可以对一些常见的字符串通过收集,枚举,碰撞等方法破解;所以为了让其破解起来更麻烦一些,所以我们一般加一点盐值(salt)并双重MD5;
例: md5(md5($password).'ylcf')
ylcf就是盐值。
4、特点
雪崩效应、定长输出和不可逆。

01背包问题基础

编 写: zhangyue
时 间: 2016-12-27
说 明: 利用背包问题解决红包使用问题

一 01背包问题

    01背包问题是指在一个容量大小固定为M的背包中,装入体积和价值不同的宝石,怎么选择才能在背包中得到最大的价值。

二 动态规划

动态规划是指
        通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以一种循环的方式去解决。
        通常基于一个递推公式和一个或多个初始状态,当前子问题的解由上一个子问题的解推出。
        有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最        好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线
        
        状态转移方程:
            d(N,M) = max(d(N-1,M), d(N-1, M-weight(i)) + value(i));
            d(N,M) 有容量为M的背包,有N个宝石
            d(N-1,M) 当前的宝石不放入背包,所能获取的最大价值
            d(N-1, M-weight(i)) + value(i) 当前宝石放入背包,所能够获取的最大价值

三 代码

function getResult($bagItems, $bagSize) {
        var result = array();
        //生成状态数组
        foreach ($i = 0; $i < $bagSize; $i ++) {
            foreach ($j = 0; $j < count($bagItems); $j ++) {
                if ($bagItems[$j]['weight'] > $i) {
                    //当前重量大于当前背包总重量
                    if (j != 0) {
                        $result[$j][$i] = $result[$j-1][$i];
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = 0;
                    }
                } else {
                    //当前重量小于背包,可以放入背包
                    if ($j != 0 ) {
                        $tmp_value = $result[$j-1][$i - $bagItems[$j]['weight']] + $bagItems[$j]['weight'];
                        $result[$j][$i] = max($result[$j-1][$i], $tmp_value);
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = $bagItems[$j]['weight'];
                    }
                }
            }
        }

        //根据得到的状态得到所选的数组
        $return  = array();//存储放回的组合
        $cur_size = $bagSize;//当前红包容量
        for ($n = count($bagItems); $n >= 0 ; $n--) {
            if ($cur_size == 0) {
                break;
            } 

            if ($n == 0 && $bagItems[$n]['weight'] < $cur_size) {
                $return[] = $bagItems[$n]['id'];
                break;
            }

            if ($bagItems[$n][$cur_size] - $bagItems[$n-1][$cur_size - $bagItems[$n]['weight']] == $bagItems[$n]['weight']) {
                //判断当前的这个商品是不是在最优解里,如果不在则不放入
                $return[] = $bagItems[$n]['id'];
                $cur_size = $cur_size - $bagItems[$n]['weight'];
            }
        }

        //得到结果
        return $return;

    }

四 递推表格

函数得到的递推表格和最终最优结果:
体积 价值 0 1 2 3 4 5 6 7 8 9 10 11
4 4 0 0 0 0 4 4 4 4 4 4 4 4
5 5 0 0 0 0 4 5 5 5 5 9 9 9
6 6 0 0 0 0 4 5 6 6 6 9 10 11
解释: 1 表格是从上到下,即4-6,从左到右,即0-11生成的 2 第一行的意思:代表在0-11的背包容量下,只有一个体积为4价值为4的宝石时,所能获得最大容量 3 第二行的意思:代表在0-11的背包容量下,有一个体积为4价值为4和体积为5价值为5的两块宝石时,所能获得最大容量 4 第三行的意思:代表在0-11的背包容量下,有一个体积为4价值为4,体积为5价值为5,体积为6价值为6的三块宝石时,所能获得最大容量 5 最终结果:[6,11] = 11 这个最优解。

五 红包问题

使用红包时,只需要将价值和体积都类比于红包的金额即可,这样可以选出最后得到的红包使用组合。
存在问题:
    1 红包会涉及小数的问题,红包现在只保留两位小数,最简单的方法是给红包*100,这样会增加递推数组的大小,增加空间复杂度
    2 红包还存在过期时间,可考虑如何加上过期时间这一条件
    3 由于红包价格和体积是同一个值,可考虑简化算法

linux定时任务的设置 crontab

一、基本使用
#分 时 日 月 周
* * * * * /home/blue/do/rsyncfile.sh

二、语法
crontab [-u username] [-l|-e|-r]
选项与参数:
-u :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作排程;
-e :编辑 crontab 的工作内容
-l :查阅 crontab 的工作内容 (备份)
-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑

三、crontab的限制
/etc/cron.allow:将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab;
/etc/cron.deny:将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab 。

以优先顺序来说, /etc/cron.allow 比 /etc/cron.deny 要优先, 而判断上面,这两个文件只选择一个来限制而已,因此,建议你只要保留一个即可, 免得影响自己在配置上面的判断!一般来说,系统默认是保留 /etc/cron.deny ,你可以将不想让他运行 crontab 的那个使用者写入 /etc/cron.deny 当中,一个帐号一行!
crontab3

四、crontab的原理
crond服务的最低侦测限制是分钟,所以cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron 里面的数据内容,因此,只要你编辑完 /etc/crontab 这个文件,并且将他储存之后,那么 cron 的配置就自动的会来运行了!

执行脚本的用户:/var/spool/cron/
执行记录:/var/log/cron
crontab2

五、crontab 的格式

代表意义 分钟 小时 日期(天) 月份 周 命令
数字范围 0-59 0-23 1-31 1-12 0-7 执行的命令
周的数字为 0 或 7 时,都代表『星期天』的意思!

辅助字符

特殊字符 代表意义
*(星号) 任何时刻
,(逗号) 代表分隔时段
-(减号) 代表一段时间范围内
/n(斜线) 代表每隔n单位间隔

六、周与日月
周和日月不是 并 的关系,而是 或 的关系。

你可以分别以周或者是日月为单位作为循环,但你不可使用「几月几号且为星期几」的模式工作。
30 12 11 11 5 root echo "just test" <==这是错误的写法
本来你以为十一月十一号且为星期五才会进行这项工作,无奈的是,系统可能会判定每个星期五作一次,或每年的 11月 11 号分别进行。

测试:(12月8号为星期4)
25 18 08 12 4 (echo "just test1" >> /tmp/test.txt ) //执行一次
25 18 07 12 4 (echo "just test2" >> /tmp/test.txt ) //执行一次
25 18 08 12 5 (echo "just test3" >> /tmp/test.txt) //执行一次

七、& 后台执行命令
1. command & : 后台运行,你关掉终端会停止运行
2. nohup command & : 后台运行,你关掉终端也会继续运行

参考:http://www.cnblogs.com/lwm-1988/archive/2011/08/20/2147299.html

八、2>&1 含义
先看一个例子:
0 2 * * * echo "just test" >> /tmp/test.txt 2>&1 &
这句话的意思就是在后台执行这条命令,并将错误输出2重定向到标准输出1,然后将标准输出1全部放到/dev/null 文件,也就是清空。

注释:
数字的含义:
0表示 键盘输入
1表示 标准输出
2表示 错误输出
>>是追加内容
> 是覆盖原有内容

示例:
0 2 * * * sh /tmp/test.sh 1>/tmp/out.file &
0 2 * * * sh /tmp/test.sh 2>/tmp/out.file &
0 2 * * * sh /tmp/test.sh 2>/tmp/out.file 2>&1 &
1、将tesh.sh 命令输出重定向到out.file, 即输出内容不打印到屏幕上,而是输出到out.file文件中。
2、2>&1 是将错误输出重定向到标准输出。 然后将标准输入重定向到文件out.file。
3、&1 表示的是文件描述1,表示标准输出,如果这里少了&就成了数字1,就表示重定向到文件1。
4 、& :后台执行

测试:
ls 2>1 : 不会报没有2文件的错误,但会输出一个空的文件1;
ls xxx 2>1: 没有xxx这个文件的错误输出到了1中;
ls xxx 2>&1: 不会生成1这个文件了,不过错误跑到标准输出了;
ls xxx >out.txt 2>&1 == ls xxx 1>out.txt 2>&1: 因为重定向符号>默认是1,这句就把错误输出和标准输出都传到out.txt 文件中。

九、注意点:2>&1写在后面的原因
格式:command > file 2>&1 == command 1> file 2>&1
首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。

如果改成: command 2>&1 >file
2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但错误输出仍然保持在终端。
crontab1

JSONP

JSONP是什么

跨域资源共享(Resources Domain Resources Sharing),客户端从不同的域名发送JSON响应时绕过浏览器限制

JSONP原理解析

利用 script标签 的 src属性 进行跨域请求,服务器响应函数调用传参。

2.1 静态方法创建

代码:

<?php
 //echo "a = 1";
?>
//html代码
<script type="text/javascript" src="http://ly.yungou.ws/test/index"></script>
<script type="text/javascript">
    console.log(a);   // 1
</script>

跨域请求成功!

2.2、 动态方法创建

动态创建 script标签的方式,添加到头部,来获取变量参数

<?php
    echo "var a = 1;";
 ?>

//通过 script语句动态创建 script标签进行请求
<script type="text/javascript">
   var script = document.createElement('script');
   script.src = 'http://ly.yungou.ws/test/index';
   var head = document.getElementsByTagName('head')[0];
   head.appendChild(script);
   console.log( a );
</script>

注意:原来动态创建 script 的方式发送请求 是异步的,虽然请求成功了,但是在使用变量时,请求还没有完成,相当于还没有定义变量,然后就报错了。
解决办法:使用callback

<?php
    echo 'callback(123)';
 ?>

<script type="text/javascript">
    var script = document.createElement('script');
    script.src = 'http://ly.yungou.ws/test/index';
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(script);

    function callback(data){
        console.log( data );    //callback(123) 对 callback 调用 输出 123
    }
</script>

那我们就可以用这种动态的方式 很轻松的 拿到后台数据了,只不过前台声明的和 后台 调用的 函数名 需要一样才行,如上面的 然而这样也不太好,每次改动,那都要前后台对接一下。

所以我们可以把回调函数名放在参数中传输。案例如下:

<?php
$callback = $_GET[ 'callback' ];    // get 通过 callback键 得到 函数名
$userInfo = array( 'username' => 'leiyuan', 'password' => '123456' );// 生成数据
$data = json_encode($userInfo);
echo "{$callback}({$data});";// hello( json_encode($arr) )

通过 script语句动态创建 script标签进行请求

    var script = document.createElement('script');
    script.src = 'http://ly.yungou.ws/test/callback?callback=hello';
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(script);
     function hello(data){
        console.log(data);// Object {username: "leiyuan", password: "123456"}        
    }
  </script>

2.3 jsonp原理:

JSONP是一个协议(并且是非正式传输协议)。 该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了.
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求,

2.4 jsonp原理

首先在客户端注册一个callback, 然后把callback的名字传给服务器。
服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

JSONP和JSON的区别:
目前为止最被推崇或者说首选的方案还是用JSON来传数据,靠JSONP来跨域。
  JSON(JavaScript Object Notation)和JSONP(JSON with Padding)
JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。一个是描述信息的格式,一个是信息传递双方约定的方法。
  1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery等框架都把jsonp作为ajax的一种形式进行了封装;
  2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加
```

JSONP使用注意事项
1、跨系统跨域名,获取基本信息,
ps:后端不能存在任何页面跳转登陆信息,否则会请求失败
2、jsonp的缺陷:不提供错误处理(对方拒绝请求,网络不通,请求地址或者参数不正确等等)如果动态插入的代码正常运行,你可以得到返回,但是如果失败了,那么什么都不会发生。
3、动态请求,都是异步请求。不支持同步请求,async无效。
请求不是通过XHR完成的,而是动态创建script标记,并请求url。跨域请求和dataType: "jsonp" 本身不支持同步操作。
4、若要在fun中使用jsonp请求后的参数,需要注意的是执行顺序,fun需要写在callback中才能成功调用参数。
5、如果没有定义jsonp和jsonpCallback,jsonp默认为"callback",jsonpCallback会是Jquery自动生成的函数名。
6、请求返回的是script tag,首先会调用jsonpCallback函数,不管是否找到该函数,都会调用success函数

参考资料

http://api.jquery.com/jQuery.ajax/

grep和find命令的基本用法:

grep命令:文本搜索

命令格式 : grep [options] pattern files
pattern 即 匹配的条件

[options]主要参数:
-c:只输出匹配行的计数。
-i:不区分字符大小写。默认区分大小写
-h:查询多文件时不显示文件名,显示文件的内容。
-l:查询多文件时只输出包含匹配字符的文件名。
-L:列出不匹配的文件名,
-n:显示匹配行及行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。

pattern正则表达式主要参数:
\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达 式的行开始。
>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:所有的单个字符。
* :有字符,长度可以为0。

files 即 匹配的文件地址 获取当前目录的地址可以使用 ./,也可以使用绝对地址/opt/.....

一些有意思的匹配:
grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配’magic’,而不是’magical’),
grep -C number pattern files :匹配的上下文分别显示[number]行,
grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。

find命令:文件搜索

命令格式:find pathname -options [-print -exec -ok ...]
参数:
pathname: find命令所查找的目录路径。例如用.来表示当前目录,也可以使用绝对地址

-print: find命令将匹配的文件输出到标准输出。

-exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' { } ;,注意{ }和;之间的空格。

-ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。

使用print将参数输出到下一条命令,使用exec或ok来执行shell命令

[options]一些常用的命令选项:
-name 按照文件名查找文件。
-perm 按照文件权限来查找文件。
-prune 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。
-user 按照文件属主来查找文件。
-group 按照文件所属的组来查找文件。
-mtime -n +n 按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。
-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
-newer file1 ! file2 查找更改时间比文件file1新但比文件file2旧的文件。
-type 查找某一类型的文件,诸如:
b - 块设备文件。
d - 目录。
c - 字符设备文件。
p - 管道文件。
l - 符号链接文件。
f - 普通文件。
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
-mount:在查找文件时不跨越文件系统mount点。
-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。

另外,下面三个的区别:

-amin n 查找系统中最后N分钟访问的文件
-atime n 查找系统中最后n24小时访问的文件
-cmin n 查找系统中最后N分钟被改变文件状态的文件
-ctime n 查找系统中最后n
24小时被改变文件状态的文件
-mmin n 查找系统中最后N分钟被改变文件数据的文件
-mtime n 查找系统中最后n*24小时被改变文件数据的文件

find命令实例:
1.在当前目录及子目录中,查找大写字母开头的txt文件
find . -name '[A-Z]*.php' -print

2.在当前及其子目录中,查找test开头的文件
find . -name 'test*' -print

3.在当前目录及子目录中,查找不是out开头的php文件
find . -name "out" -prune -o -name ".php" -print

4.查找2天内被更改过的文件
find . -mtime -2 -type f -print

5.查找超过1M的文件
find . -size +1M -type f -print

6.用grep命令在当前目录下的所有普通文件中搜索hostnames这个词
find . -name * -type f -print | xargs grep "host"

7.删除指定目录下带有“我是”的文件
find ./* - name "*.php" -print | xargs grep -l "我是" | xargs rm -rf

PHP empty、isset的差异

PHP empty、isset的差异:
1.isset():
参数           返回
''            true
0             true
false          true
null($p=null)     false
参数未定义($p)    false
其他           true

总结:如果参数存在(非NULL)则返回 TRUE,否则返回 FALSE(包括未定义)。
参数值设置为:null,返回false;
注意,isset对于NULL值变量,特殊处理。

2.empty():

参数           返回
''            true
0             true
false          true
null($p=null)     true
参数未定义($p)    true
其他           false

总结: 如果参数是非空或非零的值,则 empty() 返回 false。
未定义以及没有任何属性的对象都将被认为是空的,如果参数为空,则返回 true。

iOS博客问答摘录

最近在阅读大神Casa Taloyum博客,发现他不仅文章写得好,还尽心尽力的回复每一个人的评论,每篇文章评价都上百条,一条条看下来,受益匪浅,不仅有初学者的问题,也有开发遇到瓶颈的探讨,作者都一一解答,我就摘抄了一部分,让大家分享。

1、什么时候添加和删除notification?

答:

  • 根据最小权力原则,我们倾向于优先放在展示周期去监听事件。
    ViewController的展示周期是小于ViewController的生命周期的,所以一般如果能在展示周期完成的监听事件的需求,就不会放到生命周期中去做。除非展示周期搞不定的,才会把监听扩大到生命周期。

2、如果一个ViewController 有很多的业务,视图也比较复杂,该怎么拆分呢?我想把业务的处理和页面跳转抽取出来,放到一个category里面,这样viewController可以减少很多代码,但是这个category貌似没有复用的价值。
另外,如果UITableView里面有很多不一样的cell,如何重构代码才能使cell的逻辑简化呢?我尝试用工厂模式去解决,但是发现每个cell需要的model参数都差不多,无法通过model去区分,而通过indexPath去区分的话又不方便重用,只能是一个页面适用。

答:

  • 一般是按照业务角色来拆分业务模块,这需要你对业务有很好的抽象能力。首先,用Category来做对象功能拆分这个思路是没错的,但是对于拆分ViewController来说,拆分更加偏重的是对业务的抽象,然后设立角色,这样才能做到可复用,所以category的思路在这种场景下是不适用的。category只是把大对象变多个小对象而已,它适合拆分那种本身就已经抽象程度比较高、可复用性比较高的底层对象,而不适合用来拆分业务。

  • 独立出DataSource成一个对象,DataSource事实上就可以理解为一个factory,然后DataSource根据Controller给的指示(通过设置DataSource属性也好,通过方法穿参数也行)去生产当前需要的Cell
    继续阅读iOS博客问答摘录

solr使用进阶

快速入门主要讲的是solr管理界面,并且已经利用给好的例子做简单的搜索。
接下要做的是利用数据库是数据来建议搜索。
 
索引mysql的数据 要怎么做?
官方文档也没有详细的说明,主要是修改solrconfig.xml和schema.xml
 
一、先看下路径问题:
为什么要先看路径,是因为有些需要自己去设置。

002oYysygy70MdCwKYa0a&690

bin 常用命令脚本

contrib 各种jar包

dist 各种jar包

server web服务器

solr 未来创建的core会在该目录下

configsets  solr配置集,新建的core可以从这里拷贝配置

二、创建一个搜索实例 

1、{solr安装路径}/server/solr/新建一个文件夹命名为test

2、拷贝{solr安装路径}/server/solr/configsets/sample_techproducts_configs中的conf文件夹到test目录下

3、在后台采用如下配置,然后点击【add core】按钮完成搜索实例的添加

4、solr5.3下自带db、mail、rss、solr、tika实例

目录结构
002oYysygy70MdNZO1593&690
三、配置分词
目前sphinx用的是mmseg分词,而solr支持的分词支持较多。

1、导入smartcn的jar包

在{solr安装路径}/server/solr/test/conf/solrconfig.xml加入如下代码

<lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lucene-libs/" regex=".*smartcn.*\.jar"></lib>

2、配置分词器

在{solr安装路径}/server/solr/test/conf/schema.xml加入如下代码

<fieldType name="text_cn" class="solr.TextField" positionIncrementGap="100">
      <analyzer> 
          <tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>
          <filter class="solr.LowerCaseFilterFactory"/>     
          <filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>           
      </analyzer>
    </fieldType>

在{solr安装路径}/server/solr/test/conf/schema.xml加入如下代码

效果如图

002oYysygy70MdPaUWi3e&690

分词效果:这里的好处就是可以直接界面测试。
之前遇到的一个梗,就是123456qq
分词的结果一般都是123456和qq,所以搜123456q是搜不到的
002oYysygy70MdQ9T74ea&690
具体的分词效果,后期会再验证。这里只讲怎么配置。
四、配置导入功能

1、导入相关jar包

①mysql的jar包 

导入下载地址:https://dev.mysql.com/downloads/connector/j/

将jar放置到{solr安装路径}/dist目录下

在{solr安装路径}/server/solr/test/conf/solrconfig.xml加入如下代码

<lib dir="${solr.install.dir:../../../..}/dist/" regex="mysql.*\.jar" />

②dataimporthandler包在{solr安装路径}/server/solr/test/conf/solrconfig.xml加入如下代码

<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-.*\.jar" />
2、配置handler

在{solr安装路径}/server/solr/test/conf/solrconfig.xml加入如下代码

<requestHandler name="/dataimport" class="solr.DataImportHandler">
    <lst name="defaults">
      <str name="config">db-data-config.xml</str>
    </lst>
  </requestHandler>

3、配置数据源

在{solr安装路径}/server/solr/test/conf/下新建db-data-config.xml,配置如下:

002oYysygy70MdSCNgg44&690

002oYysygy70MdCwKYa0a&690

002oYysygy70MdSCNgg44

zzz

五、效率问题


第一次(本地)

002oYysygy70MdY8RkRc1&690

第二次(10w)

002oYysygy70MdZ0ivo12&690

第三次(100w)

002oYysygy70MdZX6nb0d&690

根据sphinx的记录
sphinx效率是5-8w docs/sec

solr是基于java单纯执行速度上比C写的sphinx慢
 
六、其他问题
1、导入不全的问题
选取的字段不能为空 如create_date为空,导入终止
2、solr的优势
sphinx的rotate选项可以动态更新索引
3、sphinx比solr建立索引的效率更快

solr入门

第一部分:了解solr

一、solr是什么?
Solr 是一个开源的企业级搜索服务器,底层使用易于扩展和修改的Java 来实现。服务器通信使用标准的HTTP 和XML,所以如果使用Solr 了解Java 技术会有用却不是必须的要求。
二、lucene是什么?

Lucene 是一个基于 Java 的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta 家族中的一个开源项目。也是目前最为流行的基于 Java 开源全文检索工具包。

目前已经有很多应用程序的搜索功能是基于 Lucene ,比如 Eclipse 帮助系统的搜索功能。Lucene 能够为文本类型的数据建立索引,所以你只要把你要索引的数据格式转化的文本格式,Lucene 就能对你的文档进行索引和搜索。

三、Solr VS Lucene

Solr 与Lucene 并不是竞争对立关系,恰恰相反Solr 依存于Lucene ,因为Solr 底层的核心技术是使用Apache Lucene 来实现的,简单的说Solr 是Lucene 的服务器化。需要注意的是Solr 并不是简单的对Lucene 进行封装,它所提供的大部分功能都区别于Lucene 。

第二部分:教程

一、从网站上下载

http://lucene.apache.org/solr/

我找的版本是5.3.1,最新版本是5.5

二、安装与运行

1、安装环境要求:

java的版本大于 1.7(利用java -version查看)

php接口是 >=5.2.11

 

2、启动:

bin/solr start -e cloud -noprompt

默认是8983端口
http://localhost:8983/solr/
快速入门solr002oYysygy70MbNH8XLf1&690
 
图片中各项的具体含义:
快速入门solr
002oYysygy70MbQv8Voee&690
002oYysygy70MbSpB5o1a&690
说明:这里是使用给好的例子,所以是有索引的。
使用 bin/solr start 是看不到索引。
其他命令
bin/solr start -p 8984(指定为8984端口)
bin/solr create -c 指定一个实例
bin/solr create -help 帮助
 
三、建立一个实例:
bin/post -c gettingstarted docs/

    -c gettingstarted:索引的名字(后期获取结果时用到)
    docs/:数据
快速入门solr002oYysygy70MbTPRJm48&690
在界面中可以看到,建立了实例。
并且也是有数据的。
 也是可以通过命令去查看的
http://localhost:8983/solr/admin/cores?action=STATUS
 
四、数据说明:
1、数据类型:索引不同类型的文档
官方文档中说:
Solr can be queried via REST clients, cURL, wget, Chrome POSTMAN, etc., as well as via the native clients available for many programming languages.

可以看出,可以建立不同形式的索引,包括json,xml,以及word

功能:添加,更新,删除等
如xml数据:
<add>
<doc>
  <field name="id">USD</field>
  <field name="name">One Dollar</field>
  <field name="manu">Bank of America</field>
  <field name="manu_id_s">boa</field>
  <field name="cat">currency</field>
  <field name="features">Coins and notes</field>
  <field name="price_c">1,USD</field>
  <field name="inStock">true</field>
</doc>
</add>
conf/schema.xml配置文件中规定好的。
 
五、怎么搜索?
1、界面搜索
http://localhost:8983/solr/#/gettingstarted_shard1_replica1/query
快速入门solr002oYysygy70Mc05TGz83&690
 

2、页面访问:

http://localhost:8983/solr/gettingstarted/select?wt=json&indent=true&q=foundation
 
六、思考:通过curl就可以获取,缺点就是不太安全吧?

如5.3上管理用户界面没有用户限制,所以任何人都可以访问管理员的用户界面将可以做任何事情与您的系统。

解决方案:基本认证和授权插件/设置防火墙
 
 
以上就是一个简单的索引的建立和搜索功能,有问题欢迎留言。

http到https的过渡

最近https有点火,搜索一下“运商商 流劫持持”,应该能看到好多运营商向网页中强制插入广告的新闻,运营商能这做一是因为流量都要从运营商过路,二是因为http传输的是明文。如果换成https传输数据,数据的安全性可以提高一个档次。

看下文之前请先看《https的使用注意事项》

http到https的切换,道理是很简单的,主要是修改对网址的解析(包括主域名和资源文件的CDN),项目里把“http://”改为“https://”或“//”(自适应协议)。下面是比较详细的改造过程:

1、改配置文件。
配置文件一般存放了项目域名、资源文件域名,所以第一步从这里下手改。
如果开启了https,$_SERVER['HTTPS']非空,一般为on(非https时,在IIS上使用ISAPI方式,该值为off)。
所以,判断是否是https访问的判断条件是 $_SERVER['HTTPS']=='on',我们用 $protocal 表示当前协议,然后把配置里的 http:// 改成 $protocal 。

2、修改项目中的绝对路径。
主要关注几个,jquery路径,二维码路径,微信js地址,轮播图地址,轮播图的点击地址,登录页面的地址。

3、外网资源文件。
如果资源文件很少,可以抓取过来放到自己网站。
如果资源文件很多,可以强制跳转到http页面。(百度图片就是强制跳转到http)

4、统计JS。
百度统计、腾讯统计均支持https,CNZZ现在也支持https(以前的cnzz统计代码不支持https)。
量子统计不支持https。

5、切换到https后可能出现的问题。
a.访问出现502错误;
b.网页打不开,加载时间非常长;
首先看是否是cdn解析问题,如果不能快速解决就切换回http。

总结:
刚始始切换后问题很多,主要特点就是“打不开”、“变慢”。多和运维做些沟通,持续优化https的体验。
https不是绝对安全,如果项目牵扯很多,改造起来难度也很大,量力而行。
记得要保证可以随时切回http。