WRITING LOG · 03

技术博客

记录技术实践、问题排查和持续成长,把每一次解决问题的过程留下来。

WORKSPACE

文章阅读

php使用mb_detect_encoding字符编码识别不准确的问题
2023-12-21
项目导入WPS做的csv文件的时候经常乱码,我自己导入的时候没问题。查了一番发现因为我是linux系统,字符编码默认utf8但同事的window默认的是GB18030。我尝试了下用mb_detect_encoding函数识别字符串编码然后用iconv转成utf8,但一直检测不了。查了一番资料发现mb_detect_encoding函数有第二个参数,mb_detect_encoding(要识别的字符串, [字符编码数组]),改成mb_detect_encoding($str, ['UTF-8','GB18030','GBK'])就正常了。
拼图小游戏
2023-12-21
空闲之余弄了个h5版本的九宫格拼图小游戏。没有用算法来打乱拼图顺序有点简单,项目突然来了没时间做优化,下面是代码:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>拼图小游戏</title>
  
</head>
<body>
  <h3>拼图游戏</h3>
  <div class="source-bg" style="display: none;">
    <canvas width="300" height="300" id="mycnavas"></canvas>
  </div>
  <div class="game-start">开始</div>
  <div class="main-box"></div>
</body>
<style>
  body {
    text-align: center;
    user-select: none;
  }
  canvas {
    border: 1px solid #fff;
    float: left;
  }
  .main-box {
    width: 306px;
    height: 306px;
    margin: auto;
    border: 1px solid #fbd;
  }
  .game-start{
    width: 300px;
    height: 40px;
    line-height: 40px;
    margin: 10px auto;
    background: #e91e6385;
    border-radius: 5px;
    cursor: pointer;
    margin: 10px auto;
    color: white;
  }
  .source-bg{
    position: fixed;
    bottom: 10vh;
    margin: 10px auto;
    width: 100%;
    text-align: center;
    justify-content: center
  }
  </style>
  <script>
  var cxt = mycnavas.getContext("2d");
  // var img = new Image();
  var img;
  var sort_idx=[];
  var cut_width = 400;
  var cut_height = 100;
  function loadImg(){
    img = new Image();
    img.src = [
      "bg.png", "618e227550061_s.jpg", "6142fd1969040_s.jpg",
      "1.png","2.png","3.jpg","4.jpg"
    ].sort(() => Math.random() - 0.5)[0];
    img.onload =()=>{
      cxt.drawImage(img, 0, 0, 400, 400);
      // cxt.drawImage(img, 0, 0, img.width, img.height);
      console.log(img.width, img.height)
      console.log(img.src)
    }
  }
  
  window.onload = function() {
    // cxt.drawImage(img, 0, 0, 400, 300);
    loadImg();
  }
  var arr = [];    //将切的图片存到数组里面
  document.getElementsByClassName("game-start")[0].onclick = function(event_btn) {
    // loadImg();
    event_btn.target.innerHTML = '重新开始';
    document.getElementsByClassName('source-bg')[0].style.display = 'none';
    var arr_cell=[];
    sort_idx=[];
    document.getElementsByClassName('main-box')[0].innerHTML = '';
    var idx = 0;
    for (var i = 0; i < 3; i++) {  
      for (var j = 0; j < 3; j++) {
        var data = cxt.getImageData(j * 100, i * 100, cut_width, cut_height);
        var canvas_img = document.createElement('canvas');
        canvas_img.width=100;
        canvas_img.height=100;
        canvas_img.classList.add('box-cell');
        var newcxt = canvas_img.getContext("2d");
        canvas_img.id = i+'_'+j;
        sort_idx.push(canvas_img.id);
        if(canvas_img.id!='2_2'){
          newcxt.putImageData(data, 0, 0);
        }else{
          end_cell = data;
          canvas_img.classList.add('empty-box');
        }
        arr_cell.push(canvas_img);
        idx++;
      }
    }
    // arr_cell.sort(() => Math.random() - 0.5); //随机打乱顺序(会出现无法复原的情况)
    sortBy(arr_cell, true);//模拟点击排序
  }
  document.getElementsByClassName('main-box')[0].onclick = function(e){
    let target = e.target;
    if(target.tagName!='CANVAS'){return;}
    move(target);
  }
  //打乱格子
  function sortBy(arr_cell, build_cell=false){
    let pp=0;
    for(let cell of arr_cell){
      cell.setAttribute('sort_id', sort_idx[pp]);
      pp++;
      if(build_cell){
        document.getElementsByClassName('main-box')[0].appendChild(cell);
      }
    }
    let ele;
    let innerFunc = function(){
      let empty_cell = document.getElementsByClassName('empty-box')[0];
      if(!empty_cell){
        return;
      }
      let point = empty_cell.getAttribute('sort_id').split('_');
      let empty_x = parseInt(point[0]);
      let empty_y = parseInt(point[1]);
      let random = [
        (empty_x+1)+'_'+empty_y,
        (empty_x-1)+'_'+empty_y,
        empty_x+'_'+(empty_y+1),
        empty_x+'_'+(empty_y-1)
      ];
      random.sort(() => Math.random() - 0.5);
      move(document.querySelector(`canvas[sort_id='${random[0]}']`), false);
    }
    for(let i=0; i<99; i++){
      setTimeout(()=>{
        innerFunc();
      },10)
    }
  }
  //移动格子
  function move(target, check=true){
    if(!target){
      return false;
    }
    let empty_cell = document.getElementsByClassName('empty-box')[0];
    let allow_move = [];
    let point = empty_cell.getAttribute('sort_id').split('_');
    let empty_x = parseInt(point[0]);
    let empty_y = parseInt(point[1]);
    let r = (empty_x+1)+'_'+empty_y;
    let l = (empty_x-1)+'_'+empty_y;
    let u = empty_x+'_'+(empty_y+1);
    let d = empty_x+'_'+(empty_y-1);
    if(target.getAttribute('sort_id')===r||
      target.getAttribute('sort_id')===l||
      target.getAttribute('sort_id')===u||
      target.getAttribute('sort_id')===d
    ){
      //取出根据坐标截取的图像, 交换canvas里面的绘图内容
      let canvas_block_target = target.getContext('2d').getImageData(0,0, cut_width, cut_height);
      let canvas_block_empty = empty_cell.getContext('2d').getImageData(0,0,cut_width,cut_width);
      let target_id = target.id+'';
      let empty_id = empty_cell.id+'';
      target.getContext("2d").putImageData(canvas_block_empty, 0, 0);
      empty_cell.getContext("2d").putImageData(canvas_block_target, 0, 0);
      target.classList.add('empty-box');
      empty_cell.classList.remove('empty-box');
      target.id = empty_id;
      empty_cell.id = target_id;
      
      check && checkEnd();
    }
  }
  //检查拼图是否完成
  function checkEnd(){
    let sort_arr=[];
    let all = document.getElementsByClassName('box-cell');
    for(let i of all){
      sort_arr.push(i.id);
    }
    if(sort_arr.join('-')===sort_idx.join('-')){
      alert('拼图成功');
      document.getElementsByClassName('source-bg')[0].style.display = 'flex';
    }
  }
  </script>
</html>
用到的图片:
nginx根据请求日志行为生成黑名单(无负载均衡版)
2023-12-06
nginx请求日志经常看到一些疑似肉鸡扫描渗透的请求骚扰不断,看了下ip地址大部分是海外的。当然服务器如果在国内并且域名也是国内的也不打算给境外提供服务那么可以直接在域名服务商那里把DNS海外解析线路直接指向127.0.0.1这种地址,从域名解析这里拒绝到绝大部分请求。麻烦点也可以自己根据ip请求行为搞黑名单。这里记录下nginx根据请求日志搞黑名单。
先理清思路:nginx一般默认配置了请求日志,可以根据日志看客户端频繁请求了哪些疑似搞破坏的内容,然后把这部分ip加入到nginx的blacklist,重新加载nginx配置就完成。
linux下bash脚本大致是这样的:
#!/bin/bash
###### 根据nginx请求日志行为特征屏蔽渗透检查的ip ######
#假设nginx用的默认配置,请求日志文件为/var/log/nginx/access.log,脚本搜索是否有请求xmlrpc.php(wordpress的漏洞脚本)
#cat /var/log/nginx/access.log | grep xmlrpc.php | cut -d " " -f 1根据日志搜索结果按空格分隔获取到客户端的ip
#sed 's/^/deny &/g'|sed 's/$/&;/g' 在搜索到的ip前后分别加上deny 和 ;
#sort|uniq 避免重复的ip
#nginx.conf默认有配置 include /etc/nginx/conf.d/*.conf,然后把黑名单ip写入到 /etc/nginx/conf.d/blacklist.conf
#最后nginx -s reload 重新加载一下nginx配置
IPS=`cat /var/log/nginx/access.log | grep xmlrpc.php | cut -d " " -f 1|sed 's/^/deny &/g'|sed 's/$/&;/g'|sort|uniq`
FILE_PATH=/etc/nginx/conf.d/blacklist.conf
for IP in $IPS
  do
  if [ `grep "$IP" -i $FILE_PATH|wc -l` -eq 0 ] ; then
   echo "$IPS" >> $FILE_PATH
   echo "$IP 加入黑名单"
  fi
done
echo "nginx重新加载配置"
/usr/sbin/nginx -s reload
以上脚本我写入到一个check_black_ip.sh文件里面,给个执行权限 chomod +x check_black_ip.sh,然后加入到crontab里面定时执行就可以了。这个脚本是在没有使用负载均衡或者代理转发的情况下有效果,如果本身请求是经过了代理或者负载均衡就要参考下nginx map 根据http_x_forwarded_for来加黑(白)名单的实现了。