-->

2012-12-09

memo: isbn

http://ja.wikipedia.org/wiki/ISBN
http://www.linein.org/blog/2007/01/05/convert-isbn10-to-isbn13-with-php/
http://d.hatena.ne.jp/hhelibex/20101001/1285960903

これは上記のサイトのphpのテストです。
"..."の内容は上記のサイトにあります。

<?php
/**
 * ISBN(ISBN-10、ISBN-13)をチェックするユーティリティ。
 * 
 * @author hhelibex
 * @see http://ja.wikipedia.org/wiki/ISBN
 */
class ISBNUtil {
...
}

/**
 * Convert ISBN10 to ISBN13 with PHP
 * 
 * @see http://www.linein.org/blog/2007/01/05/convert-isbn10-to-isbn13-with-php/
 */
function genchksum13($isbn) {
...
}

if (defined("STDIN"))
{
    // usage //
    $list = array(
        '1234567890',
        "4061592998",
        "978-4061592995",
        "4906732135",
        "978-4906732135",
        "978-4-286-13043-9",
        );
    $result = array();

    foreach ($list as $str)
    {
        $isbn13 = "";
        $maybeIsbn = "";

        print "\n" . str_repeat("=", 70) . "\n";

        $maybeIsbn = preg_replace("/[^0-9]/", "", $str);

        switch (true)
        {
        case ISBNUtil::isValidISBN10($maybeIsbn):
            print "\"{$maybeIsbn}\" is isbn10\n";

            echo $isbn13 = isbn10_to_13($maybeIsbn); // returns ISBN13
            print "\n";
            var_dump(ISBNUtil::isValidISBN13($isbn13));
            break;

        case ISBNUtil::isValidISBN13($maybeIsbn):
            print "\"{$maybeIsbn}\" is isbn13\n";
            $isbn13 = $maybeIsbn;
            break;

        default:
            trigger_error("\"{$maybeIsbn}\" is not isbn.", E_USER_NOTICE);
        }

        $result[] = array(
            "original" => $str,
            "converted" => $isbn13,
            );
    }

    print "\n// check\n";

    foreach ($result as $key1 => $val1)
    {
        print "\n" . str_repeat("=", 70) . "\n";
        print "\$key1 = {$key1}\n";
        print "\$val1[\"original\"] = {$val1["original"]}\n";
        print "\$val1[\"converted\"] = {$val1["converted"]}\n";

        foreach ($result as $key2 =>$val2)
        {
            if ($key1 !== $key2 && $val1["converted"] === $val2["converted"])
            {
                print "{$val1["original"]} == {$val2["original"]}\n";
            }
        }
    }
}

2012-12-02

memo: session.upload-progress

これはphpのsession.upload-progressのサンプルです。

# .htaccess

# テストで1GBぐらいまでOKにする。
php_value       post_max_size 1024M
php_value       upload_max_filesize 1024M

# アップロードが終わっても情報を残す。
php_value       session.upload_progress.cleanup Off

<?php
/**
 * アップロードのサンプル
 * 
 * php5.3以上
 */

function return_bytes($val)
{
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    switch($last)
    {
        // 'G' は PHP 5.1.0 以降で使用可能です
    case 'g':
        $val *= 1024;
    case 'm':
        $val *= 1024;
    case 'k':
        $val *= 1024;
    }
    return $val;
}
function MAIN()
{
    session_start();

    $fileName = basename(__FILE__);

    $uploadProgressName = "001";
    $uploadProgressId = ini_get("session.upload_progress.prefix") . $uploadProgressName;
    $uploadFile = "/tmp/abc.txt";
    $allowExt = array(
        "maxFileSize" => return_bytes(ini_get("upload_max_filesize")),
        "uploadProgressNameKey" => ini_get("session.upload_progress.name"),
        "uploadProgressNameValue" => $uploadProgressName,
        "allowExt" => array("jpg", "png", "gif", "iso"),
        );
    $action = isset($_REQUEST["action"]) ? $_REQUEST["action"] : "default";

    switch ($action)
    {
    case "uploadResult":
      print `ls -l --time-style="+%Y-%m-%d %H:%M:%S" {$uploadFile} && md5sum {$uploadFile}`;
      exit;

    case "getConfig":
        print json_encode($allowExt);
        exit;

    case "status":
        printf("%d", 100 * $_SESSION[$uploadProgressId]["bytes_processed"] / $_SESSION[$uploadProgressId]["content_length"]);
        exit;

    case "upload":
        if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadFile))
        {
            echo "File is valid, and was successfully uploaded.\n";
        }
        else
        {
            echo "Possible file upload attack!\n";
        }
        exit;

    case "default":
        break;

    default:
        trigger_error("unknown action={$action}.", E_USER_ERROR);
    }

  return array($fileName, $uploadProgressId, $uploadFile);
}

list($fileName, $uploadProgressId, $uploadFile) = MAIN();

?>
<html>
 <head>
  <meta content='IE=100' http-equiv='X-UA-Compatible'/>
  <meta content='text/css' http-equiv='Content-Style-Type'/>
  <meta content='text/javascript' http-equiv='Content-Script-Type'/>
  <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>
  <title></title>
  <script src="/js/jquery-1.8.3.min.js"></script>
  <script>
(function(){

  $(document).ready(function(){
    var waitTime = 500;
    var minWaitTime = 250;
    var fileName = function(){
      var url = window.location.pathname;
      return url.substring(url.lastIndexOf('/')+1);
    }();

    $.ajaxSetup({cache:false});

    $("form[id^=uploadProgress]").each(function(){
      var formId = $(this).attr("id");
      var formElem = $("#" + formId);
      var buttonElem = $("#" + formId + "Button");
      var inputFileElem = $("#" + formId + "InputFile");
      var barElem = $("#" + formId + "Bar");
      var messageElem = $("#" + formId + "Message");
      var config;
      var setButtonElem = function(){
        setTimeout(function(){
          if (config)
          {
            buttonElem.click(function(){
              inputFileElem.click().focus();
            });
            var inputHiddenElem = $(document.createElement("input")).attr("type", "hidden");
            formElem.prepend(inputHiddenElem.clone().
                           attr("name", config.uploadProgressNameKey).
                           attr("value", config.uploadProgressNameValue));
            formElem.prepend(inputHiddenElem.clone().attr("name", "MAX_FILE_SIZE").attr("value", config.maxFileSize));
          }
          else
          {
            setButtonElem();
          }
        }, 1000);
      };

      $.getJSON(fileName, {action:"getConfig"}, function(json){
        config = json;
        messageElem.text("拡張子: " + config.allowExt.join(", "));
      });

      setButtonElem();

      inputFileElem.change(function(){
        var startPercent = 0;
        var reloadStatus = function(){
          setTimeout(function(){
            $.get(
              fileName, {action:"status"},
              function(data, status, XHR)
              {
                var dataInt = parseInt(data, 10);
                var endPercent = dataInt;
                if (startPercent !== 0)
                {
                  if ((endPercent - startPercent) > 5)
                  {
                    waitTime = Math.max(parseInt(waitTime / 2, 10), minWaitTime);
                  }
                  else
                  {
                    waitTime = waitTime * 2;
                  }
                }

                startPercent = endPercent;

                if (!isNaN(dataInt))
                {
                  barElem.html(String(dataInt) + "%");
                  if (dataInt >= 0 && dataInt < 100)
                  {
                    reloadStatus();
                  }
                  else if (dataInt == 100)
                  {
                    $.get(fileName, {action:"uploadResult"},
                          function(data, status, XHR)
                          {
                            messageElem.text("アップロード完了: \n" + String(data)).css("white-space", "pre");
                          });
                  }
                }
              }
            );
          }, waitTime);
        };

        if (-1 == $.inArray($(this).attr("value").replace(/^.*\.([^.]+)$/, "$1").toLowerCase(), config.allowExt))
        {
          messageElem.text("拡張子エラー: " + $(this).attr("value"));
          return;
        }

        buttonElem.css("display", "none");
        formElem.submit();
        barElem.html("0%");

        reloadStatus();
      });
    });
  });
})();
  </script>
 </head>
 <body>

  <a href="<?=$fileName?>" target="">Reload</a>

  <form enctype="multipart/form-data" action="<?=$fileName?>" method="POST" id="uploadProgress001" target="uploadProgress001Result">
   <hr />
   <input type="hidden" name="action" value="upload" />
   <iframe name="uploadProgress001Result" style="display:none;"></iframe>
   <input id="uploadProgress001InputFile" style="display:none;" name="userfile" type="file" />
   <span id="uploadProgress001Button" style="cursor:pointer;color:blue;text-decoration:underline;">アップロード</span>
   <span id="uploadProgress001Bar" style="display: block;font-family: monospace;text-align: right;width: 2em;"></span>
   <span id="uploadProgress001Message"></span>
   <hr />
  </form>

  <?=htmlspecialchars(`ls -l --time-style="+%Y-%m-%d %H:%M:%S" $uploadFile`)?>
  <pre><?=htmlspecialchars(var_export($_SESSION[$uploadProgressId], true))?></pre>

 </body>
</html>

memo: ddの/dev/urandomとrsync,ssh

ddで/dev/urandom以外。
http://infobsession.net/wiki/index.php?Linux%2FOpenSSL%A4%C7%A5%C7%A5%A3%A5%B9%A5%AF%BE%C3%B5%EE

export erace_target_dev=/dev/erace_target_dev
badblocks -c 1024 -o /tmp/bb_out.txt -s -v -w $erace_target_dev
dd if=/dev/zero bs=1M | openssl enc -aes-256-ofb -k "`dd if=/dev/urandom count=2 2> /dev/null | hexdump `" | dd_rescue -w - $erace_target_dev
dd if=/dev/urandom count=1 of=$erace_target_dev
dd if=/dev/random count=16 bs=1 of=$erace_target_dev

rsyncが無いがsshがある場合のバックアップ。
http://www.linuxquestions.org/questions/linux-general-1/recursive-scp-w-o-following-links-658857/

cd /destination/directory
ssh user@remote.host "cd /original/directory; tar cf - ./" | tar xvf -

export erace_target_dev=/dev/sdb
dd if=/dev/zero bs=1M | openssl enc -aes-128-ofb -k "`dd if=/dev/urandom count=2 2> /dev/null | hexdump `" | dd_rescue -w - $erace_target_dev
dd if=/dev/urandom count=1 of=$erace_target_dev
dd if=/dev/random count=16 bs=1 of=$erace_target_dev

ssh root@192.168.0.230 "cd /mnt/gentoo; tar cf - ./" | tar xvf -