tohokuaikiのチラシの裏

技術的ネタとか。

Vue.jsのファイルをドラッグ&ドロップでIE11だけ引っかかったところ

IE11だけといいつつ、Safariは調べてないので知らない。

Vue.jsを使って

    <div class="dropArea" :class="{ dragOver: isDragOver }"
      @dragleave.prevent="onDragLeave"
      @dragover.prevent="onDragOver"
      @drop.prevent="onDrop"
      >
      <p>ここにCSVをドラッグ&ドロップしてください。</p>
    </div>

って書いたら、IE11だけ反応しなかった。普通にファイルをダウンロードしてしまう。

解決

DragEnterで引っかかっていたみたい。@dragenter.preventを入れる。

    <div class="dropArea" :class="{ dragOver: isDragOver }"
      @dragenter.prevent=""
      @dragleave.prevent="onDragLeave"
      @dragover.prevent="onDragOver"
      @drop.prevent="onDrop"
      >
      <p>ここにCSVをドラッグ&ドロップしてください。</p>
    </div>

文字列を規定の区切り文字で区切る(ったり色々する)関数

<?php
/**
 * @brief 文字列を右からN桁区切りにする
 * @param 文字列
 * @param 区切り数
 * @param 区切り文字
 * @param パディング文字
 * @param 最短文字数:足らない場合はパディングする
 * @retval
 */
function convDigit($str, $num = 3, $glue = '/', $padding = '0', $min_length = null)
{
    $str = strrev(strval($str));
    
    $ret = array();

    $fragment = "";
    for ($i=0; $i< strlen($str); $i++){
        $fragment = $str{$i}.$fragment;
        if (strlen($fragment) === $num){
            $ret[] = $fragment;
            $fragment = "";
        }
    }
    if ($fragment){
        $ret[] = sprintf('%'.$padding.$num.'s',
                         $fragment);
    }
    
    if ($min_length && $num * count($ret) < $min_length){
        $ret = array_pad($ret, ceil($min_length / $num), 
                         sprintf('%'.$padding.$num.'s', ''));
    }
    
    return implode("/", array_reverse($ret));
}

テスト

<?php
$n = "";
for ($i=1; $i<20; $i++){
     $n .= $i;
     echo convDigit($n, 3, '/', '0', 20)."\n";
}

000/000/000/000/000/000/001
000/000/000/000/000/000/012
000/000/000/000/000/000/123
000/000/000/000/000/001/234
000/000/000/000/000/012/345
000/000/000/000/000/123/456
000/000/000/000/001/234/567
000/000/000/000/012/345/678
000/000/000/000/123/456/789
000/000/000/012/345/678/910
000/000/001/234/567/891/011
000/000/123/456/789/101/112
000/012/345/678/910/111/213
001/234/567/891/011/121/314
123/456/789/101/112/131/415
012/345/678/910/111/213/141/516
001/234/567/891/011/121/314/151/617
123/456/789/101/112/131/415/161/718
012/345/678/910/111/213/141/516/171/819

日本のプロ野球の打率の推移をグラフにした

データはWikipediaより。

打率 - Wikipedia
首位打者 (日本プロ野球) - Wikipedia

f:id:tohokuaiki:20181211104744p:plain
NPBの打率グラフ

考察

  • 1975年のDHは全体には差ほど寄与してなさそう
  • 2011年の統一球はやばいだろこれっていう感じ
  • 平均打率との差が一番大きいのは、1970年の張本選手。ハリーすげぇ。

打率差ベスト20

率差 首位打者
1 1970 0.137 張本勲
2 1951 0.136 大下弘
3 1986 0.13 R.バース
4 1962 0.124 J.ブルーム
5 2000 0.123 イチロー
6 1973 0.118 王貞治
7 1989 0.118 W.クロマティ
8 1961 0.117 長嶋茂雄
9 1964 0.116 広瀬叔功
10 1957 0.115 与那嶺要
11 1994 0.114 イチロー
12 1956 0.113 与那嶺要
13 1951 0.113 川上哲治
14 2008 0.113 内川聖一
15 1966 0.113 榎本喜八
16 1980 0.109 谷沢健一
17 1969 0.108 王貞治
18 1954 0.107 与那嶺要
19 1966 0.107 長嶋茂雄
20 2015 0.107 柳田悠岐

打率差ワースト20

率差 首位打者
1 1976 0.053 吉岡悟
2 1991 0.055 平井光親
3 2005 0.055 和田一浩
4 1989 0.056 ブーマー
5 1981 0.057 落合博満
6 2009 0.06 鉄平
7 2012 0.06 角中勝也
8 2004 0.062 嶋重宣
9 1983 0.062 落合博満
10 1992 0.063 佐々木誠
11 2006 0.063 松中信彦
12 1990 0.064 J.パチョレック
13 1994 0.064 A.パウエル
14 1984 0.065 篠塚利夫
15 1975 0.065 白仁天
16 1993 0.065 辻発彦
17 2009 0.066 A.ラミレス
18 1982 0.066 落合博満
19 1975 0.067 山本浩二
20 1988 0.067 高沢秀昭

データ

セ・平均 パ・平均 セ・首率 パ・首率 セ・差分 パ・差分 セ・首位打者 パ・首位打者
1950 0.265 0.26 0.362 0.339 0.097 0.079 藤村富美男 大下弘
1951 0.264 0.247 0.377 0.383 0.113 0.136 川上哲治 大下弘
1952 0.253 0.254 0.353 0.336 0.1 0.082 西沢道夫 飯島滋弥
1953 0.255 0.247 0.347 0.318 0.092 0.071 川上哲治 岡本伊三美
1954 0.254 0.242 0.361 0.337 0.107 0.095 与那嶺要 L.レインズ
1955 0.236 0.246 0.338 0.332 0.102 0.086 川上哲治 中西太
1956 0.225 0.232 0.338 0.325 0.113 0.093 与那嶺要 豊田泰光
1957 0.228 0.235 0.343 0.331 0.115 0.096 与那嶺要 山内和弘
1958 0.231 0.236 0.32 0.314 0.089 0.078 田宮謙次郎 中西太
1959 0.23 0.241 0.334 0.323 0.104 0.082 長嶋茂雄 杉山光平
1960 0.232 0.246 0.334 0.344 0.102 0.098 長嶋茂雄 榎本喜八
1961 0.236 0.248 0.353 0.336 0.117 0.088 長嶋茂雄 張本勲
1962 0.231 0.25 0.307 0.374 0.076 0.124 森永勝治 J.ブルーム
1963 0.244 0.244 0.341 0.335 0.097 0.091 長嶋茂雄 J.ブルーム
1964 0.245 0.25 0.323 0.366 0.078 0.116 江藤愼一 広瀬叔功
1965 0.235 0.24 0.336 0.32 0.101 0.08 江藤愼一 野村克也
1966 0.237 0.238 0.344 0.351 0.107 0.113 長嶋茂雄 榎本喜八
1967 0.245 0.243 0.343 0.336 0.098 0.093 中暁生 張本勲
1968 0.24 0.244 0.326 0.336 0.086 0.092 王貞治 張本勲
1969 0.237 0.246 0.345 0.333 0.108 0.087 王貞治 永淵洋三・張本勲
1970 0.234 0.246 0.325 0.383 0.091 0.137 王貞治 張本勲
1971 0.23 0.253 0.32 0.337 0.09 0.084 長嶋茂雄 江藤愼一
1972 0.245 0.256 0.329 0.358 0.084 0.102 若松勉 張本勲
1973 0.237 0.254 0.355 0.337 0.118 0.083 王貞治 加藤秀司
1974 0.249 0.247 0.332 0.34 0.083 0.093 王貞治 張本勲
1975 0.252 0.254 0.319 0.319 0.067 0.065 山本浩二 白仁天
1976 0.265 0.256 0.355 0.309 0.09 0.053 谷沢健一 吉岡悟
1977 0.271 0.255 0.358 0.329 0.087 0.074 若松勉 有藤道世
1978 0.269 0.265 0.348 0.354 0.079 0.089 水谷実雄 佐々木恭介
1979 0.262 0.274 0.346 0.364 0.084 0.09 F.ミヤーン 加藤英司
1980 0.26 0.273 0.369 0.358 0.109 0.085 谷沢健一 L.リー
1981 0.265 0.269 0.358 0.326 0.093 0.057 藤田平 落合博満
1982 0.255 0.259 0.351 0.325 0.096 0.066 長崎啓二 落合博満
1983 0.27 0.27 0.353 0.332 0.083 0.062 真弓明信 落合博満
1984 0.269 0.265 0.334 0.355 0.065 0.09 篠塚利夫 ブーマー
1985 0.272 0.272 0.35 0.367 0.078 0.095 R.バース 落合博満
1986 0.259 0.27 0.389 0.36 0.13 0.09 R.バース 落合博満
1987 0.263 0.263 0.333 0.366 0.07 0.103 篠塚利夫正田耕三 新井宏昌
1988 0.256 0.26 0.34 0.327 0.084 0.067 正田耕三 高沢秀昭
1989 0.26 0.266 0.378 0.322 0.118 0.056 W.クロマティ ブーマー
1990 0.262 0.264 0.326 0.338 0.064 0.074 J.パチョレック 西村徳文
1991 0.256 0.259 0.34 0.314 0.084 0.055 古田敦也 平井光親
1992 0.256 0.259 0.331 0.322 0.075 0.063 J.ハウエル 佐々木誠
1993 0.252 0.254 0.329 0.319 0.077 0.065 T.オマリー 辻発彦
1994 0.26 0.271 0.324 0.385 0.064 0.114 A.パウエル イチロー
1995 0.255 0.248 0.355 0.342 0.1 0.094 A.パウエル イチロー
1996 0.265 0.258 0.34 0.356 0.075 0.098 A.パウエル イチロー
1997 0.258 0.266 0.335 0.345 0.077 0.079 鈴木尚典 イチロー
1998 0.259 0.265 0.337 0.358 0.078 0.093 鈴木尚典 イチロー
1999 0.268 0.259 0.369 0.343 0.101 0.084 R.ローズ イチロー
2000 0.262 0.264 0.346 0.387 0.084 0.123 金城龍彦 イチロー
2001 0.263 0.264 0.333 0.346 0.07 0.082 松井秀喜 福浦和也
2002 0.257 0.255 0.343 0.34 0.086 0.085 福留孝介 小笠原道大
2003 0.269 0.276 0.34 0.36 0.071 0.084 今岡誠 小笠原道大
2004 0.275 0.277 0.337 0.358 0.062 0.081 嶋重宣 松中信彦
2005 0.27 0.267 0.344 0.322 0.074 0.055 青木宣親 和田一浩
2006 0.263 0.261 0.351 0.324 0.088 0.063 福留孝介 松中信彦
2007 0.265 0.262 0.346 0.334 0.081 0.072 青木宣親 稲葉篤紀
2008 0.265 0.265 0.378 0.332 0.113 0.067 内川聖一 リック
2009 0.256 0.267 0.322 0.327 0.066 0.06 A.ラミレス 鉄平
2010 0.267 0.27 0.358 0.346 0.091 0.076 青木宣親 西岡剛
2011 0.242 0.251 0.316 0.338 0.074 0.087 長野久義 内川聖一
2012 0.244 0.252 0.34 0.312 0.096 0.06 阿部慎之助 角中勝也
2013 0.254 0.262 0.333 0.341 0.079 0.079 T.ブランコ 長谷川勇也
2014 0.264 0.257 0.338 0.331 0.074 0.074 M.マートン 糸井嘉男
2015 0.249 0.256 0.336 0.363 0.087 0.107 川端慎吾 柳田悠岐
2016 0.253 0.259 0.344 0.339 0.091 0.08 坂本勇人 角中勝也
2017 0.251 0.25 0.323 0.322 0.072 0.072 宮崎敏郎 秋山翔吾
2018 0.259 0.254 0.348 0.352 0.089 0.098 D.ビシエド 柳田悠岐

今更ながらクロスドメインのAjaxをする場合

1分でわかるようにメモ。

Ajaxを送る側(http://send.example.com/send_ajax.html

<html>
<head>
<script
  src="https://code.jquery.com/jquery-1.12.4.min.js"
  integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
  crossorigin="anonymous"></script>
  <script>
$(function(){
    $('#b').on('click', function(e){
        $.ajax({
          url: 'http://receive.example.com/catch.php',
          xhrFields: {
            withCredentials: true
          },          
          cache: false,
          data: {
              foo: 'var'
          }
        }).success(function(data, status, xhr){
            $('#foo').html(data);
        }).error(function(xhr, status, data){
            console.log("error"); 
        })
    });
});
  </script>
</head>
<body>
  <div id="foo">foo</div>
  <button id="b">click</button>
</body>
</html>

f:id:tohokuaiki:20181130154434p:plain

Ajaxを受信する側(https://receive.example.com/catch.php

<?php
session_start();
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Origin: http://send.example.com');
$_SESSION['counter'] += 1;
?>
Hello 
<?php
printf('<b>%d</b>times %s', $_SESSION['counter'], time());
?>

これで、先ほどボタンをクリックすると

f:id:tohokuaiki:20181130154702p:plain

となる。送り側の、xhrFields と受け側の header("Access-Control-Allow-Credentials: true"); はCOOKIEを使わないなら不要。

PHPでアクセスしてきたIPアドレスがプライベートアドレスかをチェックする

プライベートIPは以下の範囲で

10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255

PHPip2longをかませると

167772160~184549375
2886729728~2887778303
3232235520~3232301055

なので、こんな感じで。

<?php
function isPrivateAddress($ip = null)
{
    is_null($ip) and $ip = $_SERVER['REMOTE_ADDR'];
    
    $iplong = ip2long($ip);
    $iplong = sprintf('%u', $iplong); // for 32bit architecture
    
    return ($iplong >= 167772160 && $iplong <=184549375) ||
           ($iplong >= 2886729728 && $iplong <=2887778303) ||
           ($iplong >= 3232235520 && $iplong <=3232301055) ;
}

テスト

<?php
$testips=<<<EOF
10.0.0.0
10.0.0.1
10.0.1.1
10.255.255.254
10.255.255.255
11.0.0.1
172.15.234.1
172.16.0.0
172.16.0.1
172.31.255.254
172.31.255.255
172.32.0.1
191.255.255.255
192.168.0.0
192.168.0.1
192.168.255.254
192.168.255.255
193.0.0.1
EOF;

foreach (explode("\n", $testips) as $ip){
    $ip = trim($ip);
    $long = ip2long($ip);
    printf("%s\t(%u)\t=>\t%s\n",
           $ip, $long,
           isPrivateAddress($ip) ? 'private' : 'global');
}

10.0.0.0        (167772160)     =>      private
10.0.0.1        (167772161)     =>      private
10.0.1.1        (167772417)     =>      private
10.255.255.254  (184549374)     =>      private
10.255.255.255  (184549375)     =>      private
11.0.0.1        (184549377)     =>      global
172.15.234.1    (2886724097)    =>      global
172.16.0.0      (2886729728)    =>      private
172.16.0.1      (2886729729)    =>      private
172.31.255.254  (2887778302)    =>      private
172.31.255.255  (2887778303)    =>      private
172.32.0.1      (2887778305)    =>      global
191.255.255.255 (3221225471)    =>      global
192.168.0.0     (3232235520)    =>      private
192.168.0.1     (3232235521)    =>      private
192.168.255.254 (3232301054)    =>      private
192.168.255.255 (3232301055)    =>      private
193.0.0.1       (3238002689)    =>      global