Python 二进制转十进制

二进制转十进制的原理相对简单。
假设有二进制数为abc.def,对应的十进制数为A.B
那么整数部分A = a*2^2 + b*2^1 + c*2^0, 小数部分B = d*2^(-1) + e*2^(-2) + f*2^(-3)
实现程序如下:

# 二进制转十进制
def binary_to_decimal(binary):
    decimal = 0
    integer_part, fractional_part = binary.split('.')  # 拆分整数部分和小数部分

    # 转换整数部分为十进制
    for i in range(len(integer_part)):
        digit = int(integer_part[i])
        power = len(integer_part) - i - 1
        decimal += digit * (2 ** power)

    # 转换小数部分为十进制
    for i in range(len(fractional_part)):
        digit = int(fractional_part[i])
        power = -(i + 1)
        decimal += digit * (2 ** power)

    return decimal

Python 十进制(可包含小数)转二进制

原理

假设有十进制数A.B,对应的二进制数为abc.def
整数部分A = a*2^2 + b*2^1 + c*2^0,所以当A除以2时,得到a*2^1 + b*2^0和余数c除2取余)。
同理,小数部分B = d*2^(-1) + e*2^(-2) + f*2^(-3),当B乘以2时,B*2 - d = e*2^(-1) + f*2^(-2),即 B*2的整数部分求出了d乘2取整)。

所以十进制转换成二进制算法如下:

def decimal_to_binary(decimal):
    integer_part = int(decimal)  # 提取整数部分
    fractional_part = decimal - integer_part  # 提取小数部分

    # 转换整数部分为二进制
    binary_integer = ""
    if integer_part == 0:
        binary_integer = "0"  # 十进制数为0时,二进制为0
    else:
        while integer_part > 0:
            binary_integer = str(integer_part % 2) + binary_integer
            integer_part = integer_part // 2

    # 转换小数部分为二进制
    binary_fractional = ""
    while fractional_part > 0:
        fractional_part *= 2
        bit = int(fractional_part)
        binary_fractional += str(bit)
        fractional_part -= bit
        if len(binary_fractional) > 12:
            break  # 限制小数部分的位数为12位

    binary = binary_integer
    if binary_fractional != "":
        binary += "." + binary_fractional

    return binary

pptpd开启日志记录功能

1 开启pptp日志记录选项

编辑文件 /etc/ppp/options.pptpd
找到nologfd(表示不记录日志),将其注释掉
然后,增加一行 logfile /var/log/pptpd.log,记录日志到文件

2 vpn登录/断开时,增加自定义日志记录

vpn登录和断开的时候,会自动执行/etc/ppp/ip-up/etc/ppp/ip-down两个脚本,查看这两个脚本,会发现有这样一行
This file should not be modified -- make local changes to /etc/ppp/ip-up.local instead
也就是说这两个脚本不要修改,如果要添加自定义的功能,修改ip-up.localip-down.local脚本。

另外需要注意的是,上面的脚本被调用时是有命令行参数的,具体如下:

$PEERNAME: 用户名
$1: 分配的ppp设备
$4: VPN服务器的IP
$5: 分配给客户端的内网IP
$6: 客户端真实公网IP

- 阅读剩余部分 -

Ueditor 更新百度地图JS API

如果页面上的百度地图组件显示:您所使用的地图JS API版本过低,已不再维护,为保证地图基本功能 正常使用,请尽快升级到最新版地图JS API,那么,你需要对百度地图API进行升级了。

首先,你需要到百度地图开放平台进行账号注册获取AK密钥等操作(操作文档)。
然后找到ueditor的百度地图组件,对相关文件进行修改,路径为:/path/to/ueditor/dialogs/map
1、修改map.html,将
<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.1&services=true"></script>
替换为
<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=你的AK密钥"></script>

- 阅读剩余部分 -

升级PHP7之后微信公众号开发遇到的几个问题

由于微信公众号官方给出的示例代码都是比较老旧的,基本支持的都是PHP5.6以前的版本。如果将PHP版本升级到PHP7,那么代码无法正常运行,大概有下面几个问题:

一、$GLOBALS["HTTP_RAW_POST_DATA"] 失效

原因:经过在网上查询发现 PHP >= 5.6 的时候 HTTP_RAW_POST_DATA 被移除了。但是 PHP = 5.6 还可以在配置文件 php.ini 还能找到 always_populate_raw_post_data 选项。当 PHP >= 7.0 就已经彻底移除了 always_populate_raw_post_data 配置。
解决方案:使用file_get_contents('php://input');代替。

二、提示构造函数deprecated

原因:自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。不使用命名空间中的类则不受影响。
解决方案:修改pkcs7Encoder.phpwxBizMsgCrypt.php两个文件中的构造函数,使用__construct即可。

三、mcrypt_module_open函数报错

原因:在 PHP7mcrypt_module_open()已经被 OPENSSL 取代。
解决方案:修改pkcs7Encoder.php文件中Prpcrypt类的encryptdecrypt方法,重点是使用openssl_encryptopenssl_decrypt代替mcrypt_开头的函数。为避免表达不清楚,将代码贴在下面。

public function encrypt($text, $appid)
{

    try {
        // 获得16位随机字符串,填充到明文之前
        $random = $this->getRandomStr();
        $text = $random . pack("N", strlen($text)) . $text . $appid;
        // 网络字节序
//         $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
//         $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
        $iv = substr($this->key, 0, 16);
        //使用自定义的填充方式对明文进行补位填充
        $pkc_encoder = new PKCS7Encoder;
        $text = $pkc_encoder->encode($text);
//         mcrypt_generic_init($module, $this->key, $iv);
//         //加密
//         $encrypted = mcrypt_generic($module, $text);
// 下面这句是重点,使用openssl方法
        $encrypted = openssl_encrypt($text, 'AES-256-CBC', $this->key, OPENSSL_ZERO_PADDING, $iv);
//         mcrypt_generic_deinit($module);
//         mcrypt_module_close($module);

        //print(base64_encode($encrypted));
        //使用BASE64对加密后的字符串进行编码
//         return array(ErrorCode::$OK, base64_encode($encrypted));
        return array(ErrorCode::$OK, $encrypted);
    } catch (Exception $e) {
        //print $e;
        return array(ErrorCode::$EncryptAESError, null);
    }
}

// 只截取了一部分
public function decrypt($encrypted, $appid)
{

    try {
        //使用BASE64对需要解密的字符串进行解码
//         $ciphertext_dec = base64_decode($encrypted);
//         $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
        $iv = substr($this->key, 0, 16);
//         mcrypt_generic_init($module, $this->key, $iv);

//         //解密
//         $decrypted = mdecrypt_generic($module, $ciphertext_dec);
//         mcrypt_generic_deinit($module);
//         mcrypt_module_close($module);
        $decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $this->key, OPENSSL_ZERO_PADDING, $iv);
    } catch (Exception $e) {
        return array(ErrorCode::$DecryptAESError, null);
    }
...