dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.61.dylib报错

周六用brew安装了ffmpeg,然后PHP就不能用了

dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.61.dylib
  Referenced from: /usr/local/Cellar/php@7.0/7.0.30/bin/php
  Reason: image not found
Abort trap: 6

网上搜到下面的解决办法:

https://qiita.com/yasu_yyy/items/2f6a6b0bc562f082d999

发表在 php异常 | 留下评论

tcpdump 抓取http请求、响应

tcpdump安装略过。

1.监听eth0网卡HTTP 80端口的request和response
tcpdump -i eth0 -A -s 0 ‘tcp port 80 and (((ip[2:2] – ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)’

2.监听eth0网卡HTTP 80端口的request(不包括response),指定来源域名”example.com”,也可以指定IP”192.168.1.107″
tcpdump -i eth0 -A -s 0 ‘src example.com and tcp port 80 and (((ip[2:2] – ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)’

3.监听本机发送至本机的HTTP 80端口的request和response
tcpdump -i lo -A -s 0 ‘tcp port 80 and (((ip[2:2] – ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)’

4.监听eth0网卡HTTP 80端口的request和response,结果另存为cap文件
tcpdump -i eth0 -A -s 0 ‘tcp port 80 and (((ip[2:2] – ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)’ -w ./dump.cap

注1:如果报错”tcpdump: Bluetooth link-layer type filtering not implemented”,是因为默认网卡不是ech0,需要用-i参数指定

注2:通过ifconfig命令查看网卡

End;

原文出自:http://blog.csdn.net/daiyudong2020/article/details/71375256
———————
作者:带鱼兄
来源:CSDN
原文:https://blog.csdn.net/daiyudong2020/article/details/71375256
版权声明:本文为博主原创文章,转载请附上博文链接!

可以将内容进行收集 tcpdump tcp -w dump.cap,然后tcpdump -ttttr dump.cap > dump.out,查看具体的内容

发表在 小技巧 | 留下评论

iptables 限速规则

看到一个很好的比喻:

limit match的工作方式就像一个单位大门口的保安,当有人要 进入时,需要找他办理通行证。早上上班时,保安手里有一定数量的通行证,来一个人,就签发一个,当通 行证用完后,再来人就进不去了,但他们不会等,而是到别的地方去(在iptables里,这相当于一个包不符 合某条规则,就会由后面的规则来处理,如果都不符合,就由缺省的策略处理)。但有个规定,每隔一段时 间保安就要签发一个新的通行证。这样,后面来的人如果恰巧赶上,也就可以进去了。如果没有人来,那通 行证就保留下来,以备来的人用。如果一直没人来,可用的通行证的数量就增加了,但不是无限增大的,最 多也就是刚开始时保安手里有的那个数量。也就是说,刚开始时,通行证的数量是有限的,但每隔一段时间 就有新的通行证可用。limit match有两个参数就对应这种情况,–limit-burst指 定刚开始时有多少通行证可用,–limit指定要隔多长时间才能签发一个新的通行 证。要注意的是,我这里强调的是“签发一个新的通行证”,这是以iptables的角度考虑的。在你自己写规 则时,就要从这个角度考虑。比如,你指定了–limit 3/minute –limit-burst 5 ,意思是开始时有5个通行证,用完之后每20秒增加一个(这就是从iptables的角度看的,要是以用户 的角度看,说法就是每一分钟增加三个或者每分钟只能过三个)。你要是想每20分钟过一个,只能写成–limit 3/hour –limit-burst 5,也就是说你要把时间单位凑成整的。

http://blog.sina.com.cn/s/blog_6e5e78bf0101tuq9.html#cmt_576A0F6E-7F000001-BD7CE1BB-8DB-8A0

发表在 linux | 留下评论

ssh快速搭建安全稳定的代理服务

1、通过本地的ssh与远程的(能科学上网的)机器建立一个安全隧道: 本地建立ssh进行端口监听
ssh -N -D 127.0.0.1:3128 用户名@remote_ip(能科学上网的)

2、本地浏览器将请求全部发送到本地的3128端口

具体参考下面

https://www.liaohuqiu.net/cn/posts/setup-web-prorxy-by-ssh-tunnel/

扩展思考
openVPN也可以配合ssh进行科学上网名,以下为链接

http://www.classy.dk/hacks/archives/002287.html

发表在 http, 小技巧 | 留下评论

基于谷歌动态口令的自动登录脚本

item2loginForGA.sh

#!/usr/bin/expect

set timeout 30

set port [lindex $argv 0]
set user [lindex $argv 1]
set host [lindex $argv 2]
set pass [lindex $argv 3]
set secret [lindex $argv 4]

set gaCode [exec /usr/local/bin/php /Users/wenzg/local/tools/GoogleAuthenticator.php $secret]

spawn ssh -p $port $user@$host

expect {
  timeout { send_user "\nFailed to get verify code prompt\n"; exit 1 }
  "*erification code:" {send "$gaCode\r"}
}

expect {
   timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
   "*assword:" {send "$pass\r"}
}

interact

GoogleAuthenticator.php

getCode($secret);

class PHPGangsta_GoogleAuthenticator
{
    protected $_codeLength = 6;

    /**
     * Create new secret.
     * 16 characters, randomly chosen from the allowed base32 characters.
     *
     * @param int $secretLength
     *
     * @return string
     */
    public function createSecret($secretLength = 16)
    {
        $validChars = $this->_getBase32LookupTable();

        // Valid secret lengths are 80 to 640 bits
        if ($secretLength < 16 || $secretLength > 128) {
            throw new Exception('Bad secret length');
        }
        $secret = '';
        $rnd = false;
        if (function_exists('random_bytes')) {
            $rnd = random_bytes($secretLength);
        } elseif (function_exists('mcrypt_create_iv')) {
            $rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
        } elseif (function_exists('openssl_random_pseudo_bytes')) {
            $rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
            if (!$cryptoStrong) {
                $rnd = false;
            }
        }
        if ($rnd !== false) {
            for ($i = 0; $i < $secretLength; ++$i) {
                $secret .= $validChars[ord($rnd[$i]) & 31];
            }
        } else {
            throw new Exception('No source of secure random');
        }

        return $secret;
    }

    /**
     * Calculate the code, with given secret and point in time.
     *
     * @param string   $secret
     * @param int|null $timeSlice
     *
     * @return string
     */
    public function getCode($secret, $timeSlice = null)
    {
        if ($timeSlice === null) {
            $timeSlice = floor(time() / 30);
        }

        $secretkey = $this->_base32Decode($secret);

        // Pack time into binary string
        $time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
        // Hash it with users secret key
        $hm = hash_hmac('SHA1', $time, $secretkey, true);
        // Use last nipple of result as index/offset
        $offset = ord(substr($hm, -1)) & 0x0F;
        // grab 4 bytes of the result
        $hashpart = substr($hm, $offset, 4);

        // Unpak binary value
        $value = unpack('N', $hashpart);
        $value = $value[1];
        // Only 32 bits
        $value = $value & 0x7FFFFFFF;

        $modulo = pow(10, $this->_codeLength);

        return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
    }

    /**
     * Get QR-Code URL for image, from google charts.
     *
     * @param string $name
     * @param string $secret
     * @param string $title
     * @param array  $params
     *
     * @return string
     */
    public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
    {
        $width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
        $height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
        $level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';

        $urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
        if (isset($title)) {
            $urlencoded .= urlencode('&issuer='.urlencode($title));
        }

        return 'https://chart.googleapis.com/chart?chs='.$width.'x'.$height.'&chld='.$level.'|0&cht=qr&chl='.$urlencoded.'';
    }

    /**
     * Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
     *
     * @param string   $secret
     * @param string   $code
     * @param int      $discrepancy      This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
     * @param int|null $currentTimeSlice time slice if we want use other that time()
     *
     * @return bool
     */
    public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
    {
        if ($currentTimeSlice === null) {
            $currentTimeSlice = floor(time() / 30);
        }

        if (strlen($code) != 6) {
            return false;
        }

        for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
            $calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
            if ($this->timingSafeEquals($calculatedCode, $code)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Set the code length, should be >=6.
     *
     * @param int $length
     *
     * @return PHPGangsta_GoogleAuthenticator
     */
    public function setCodeLength($length)
    {
        $this->_codeLength = $length;

        return $this;
    }

    /**
     * Helper class to decode base32.
     *
     * @param $secret
     *
     * @return bool|string
     */
    protected function _base32Decode($secret)
    {
        if (empty($secret)) {
            return '';
        }

        $base32chars = $this->_getBase32LookupTable();
        $base32charsFlipped = array_flip($base32chars);

        $paddingCharCount = substr_count($secret, $base32chars[32]);
        $allowedValues = array(6, 4, 3, 1, 0);
        if (!in_array($paddingCharCount, $allowedValues)) {
            return false;
        }
        for ($i = 0; $i < 4; ++$i) {
            if ($paddingCharCount == $allowedValues[$i] &&
                substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
                return false;
            }
        }
        $secret = str_replace('=', '', $secret);
        $secret = str_split($secret);
        $binaryString = '';
        for ($i = 0; $i < count($secret); $i = $i + 8) {
            $x = '';
            if (!in_array($secret[$i], $base32chars)) {
                return false;
            }
            for ($j = 0; $j < 8; ++$j) {
                $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
            }
            $eightBits = str_split($x, 8);
            for ($z = 0; $z < count($eightBits); ++$z) {
                $binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
            }
        }

        return $binaryString;
    }

    /**
     * Get array with all 32 characters for decoding from/encoding to base32.
     *
     * @return array
     */
    protected function _getBase32LookupTable()
    {
        return array(
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
            'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
            '=',  // padding char
        );
    }

    /**
     * A timing safe equals comparison
     * more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
     *
     * @param string $safeString The internal (safe) value to be checked
     * @param string $userString The user submitted (unsafe) value
     *
     * @return bool True if the two strings are identical
     */
    private function timingSafeEquals($safeString, $userString)
    {
        if (function_exists('hash_equals')) {
            return hash_equals($safeString, $userString);
        }
        $safeLen = strlen($safeString);
        $userLen = strlen($userString);

        if ($userLen != $safeLen) {
            return false;
        }

        $result = 0;

        for ($i = 0; $i < $userLen; ++$i) {
            $result |= (ord($safeString[$i]) ^ ord($userString[$i]));
        }

        // They are only identical strings if $result is exactly 0...
        return $result === 0;
    }
}
发表在 bash, 扒拉代码 | 留下评论

什么是贫血模型、充血模型

今天看了知乎的一个帖子,感觉顿时豁然开朗,贫血、充血貌似最初是java框架中发现的,下面说下我的理解.

我们做面向对象开发时,需要设计类如何构成,类由属性(变量、常量)和方法(行为)构成,方法其实是包含业务逻辑的,贫血模型不包含业务逻辑(可能只有geter、setter方法来获取属性),而充血模型既包含属性,又包含业务逻辑

拿帖子里的例子来书,如果我们设计一个用户的对象(User)

贫血模型:
需要两个类:
1、User 包含用户Id、用户名称的get、set
2、UserLogic 包含用户相关的操作,getUserInfo(), create(User), update(User) 等

使用的时候就这样: (new UserLogic())->create(new User(['name' => 'George']));

充血模型:
需要一个类:
1、User 包含用户相关的所有操作

使用的时候就这样: (new User())->create(['name' => 'George']);

我恍然大悟,上面两个模型我其实都用过了,目前工作中充血用的比较多,自己的项目贫血用的多

发表在 扫盲 | 留下评论

git 分支重命名

1. Rename your local branch.
If you are on the branch you want to rename:

git branch -m new-name
If you are on a different branch:

git branch -m old-name new-name

2. Delete the old-name remote branch and push the new-name local branch.

git push origin :o ld-name new-name

3. Reset the upstream branch for the new-name local branch.
Switch to the branch and then:

git push origin -u new-name
发表在 git | 留下评论

第一个Java程序

第一步: 安装Java环境,安装JDK (java开发套件)
第二步: 编写 Hi.java

public class Hi
{
    public static void main(String[] args)
    {
        System.out.println("Hello World!");
    }
}

第三步: 编译
javac Hi.java

第四步: 运行
java Hi

发表在 java | 留下评论

逐行读取文件

download_list=$1

while read LINE;
do
video_url=`echo $LINE |awk ‘{print $1}’`
video_name=`echo $LINE |awk ‘{print $2}’`

php crawer.php $video_url $video_name
done < $download_list

发表在 awk, 小工具 | 留下评论

设计模式PHP具体实现

设计模式主要有几个大类,除了经典的GOF 23个模式以外,还有其它后续出现的很多,主要分为: 结构型、创建型、行为型、其它类 四大类,在这里记录下自己的学习过程

参考文档:

https://designpatternsphp.readthedocs.io/zh_CN/latest/

https://github.com/domnikl/DesignPatternsPHP

https://laravelacademy.org/category/design-patterns

自己的实现记录在 https://github.com/hihaowen/DesignPattern

行为型:
中介者 ok
模版方法 ok
策略 ok
状态 ok
观察者 ok
责任链 ok
命令 ok
迭代器 ok
纪念品 ok
空对象 ok
访问者 ok
解释器 ok
规格模式 ok

结构型:
适配器 ok
桥接 ok
依赖注入 ok
外观 ok
装饰 ok
代理 ok
组合 ok
享元模式 ok
注册模式 ok
流式接口 ok

创建型:
生成器 (建造者) ok
抽象工厂 ok
简单工厂 ok
工厂方法 ok
静态工厂 ok
对象池 ok
原型 ok
单例 ok

其它:
服务定位器 ok

发表在 DesignPattern | 留下评论