第 13 回 HTMLのプログラミング

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

13-1. HTMLアプリの例

  1. 正規表現電卓第2回演習2-2
  2. かみしばい順序木 ヒープの追加
  3. 暗号のツー ル

演習13-1

RSA鍵を作成しなさい

演習13-2

次の暗号を解読しなさい

Avrfv Klurp Bupclyzpaf (AKB) dhz mvbuklk pu 1907 if adv fvbun lunpullyz dov wshflk hjapcl yvslz pu aol pukbzayphs dvysk, Zlppjop Opyvah huk Zopurpjop Vnptvav, av jvujylapgl aolpy zbisptl pklh, “Wyvtvapun lunpullypun lkbjhapvu pz pukllk aol mvbukhapvu mvy aol klclsvwtlua vm h uhapvu.”

ヒント

シーザー暗号解読機を用いると簡単

演習13-3

RSA 暗号鍵作成シートを用いて RSA暗号を作りなさい。 また、べき乗電卓を用いて、暗号の確認をしなさい

演習13-4

次の暗号を解きなさい

Hudxu Zyldg Klgpybvghx (HZK) nsv iuklzyz gl 1907 ex hnu xuklo yloglyybv nau cmsxyz srhgpy bumyv gl hay glzkvhbgsm nubmz, Vyggrag Agbuhs slz Vagldgrag Uogquhu, hu rulrbyhgjy haygb vkemgqy gzys, “Cbuquhglo yloglyybglo yzkrshgul gv glzyyz hay iuklzshgul iub hay zypymucqylh ui s lshgul.” Habukoa ghv vumgz slz zgmgoylh srszyqgr rkmhkby, HZK asv eyyl iuvhybglo vhkzylhv iub quby hasl s rylhkbx ngha hay qgvvgul, “Zypymucqylh ui Akqsl Byvukbryv Nau Rulhbgekhy hu Vurgyhx ex Hyralumuox.” HZK smvu asv eyyl cbupgzglo fksmghx glvhbkrhgul esvyz ul hay hnu yzkrshgulsm qswgqv: “Byvcyrh iub Cbsrhgrsm Vhkzx” slz “Vhkzylhv Igbvh.” HZK rulhglkyv hu rkmhgpshy ywrymmylh akqsl byvukbryv hu qyyh hay lyyzv ui vurgyhx, rasloglo ngha hay hgqyv hu qsdy vgolgigrslh rulhbgekhgulv hu hay zypymucqylh ui Tscsl’v vrgylry slz hyralumuox.

ヒント

単一換字式暗号解読機を用いる

13-2. HTMLのプログラミング

bekijo.js

暗号などで使用する、 xy (modn) (xy乗 を nで割った余り) を計算するべき乗電卓を紹介します。

bekijo.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>power caluculator</title>
<script type="text/javascript" src="calc.js"></script>
<style>
input { width:5em;}
</style>
</head>
<body>
<h1>べき乗電卓</h1>
<form name="calcform">
<p>
<input type="number" name="a" value="0"><sup>
<input type="number" name="b" value="1"></sup>
 mod
<input type="number" name="n" value="1">
<input type="button" value="&equiv;(計算)" onClick="calc();">
<!--<span id="result">0</span>-->
<input type="number" name="result" value="0">
</p>
<p>
<input type="reset" >
</p>
</form>
</body>
</html>

calc.js


function power(a,b,n){
    if(b==0) return 1;
    var result = power(a,parseInt(b/2),n);
    return (result*result*(b%2==0?1:a) )% n;
}
function calc(){
    var a = parseInt(document.calcform.a.value);
    var b = parseInt(document.calcform.b.value);
    var n= parseInt(document.calcform.n.value);
    document.calcform.result.value = power(a,b,n);
}

使い方

出力欄以外に数値を入れて、計算ボタンを押すと計算結果が出ます。

例えばRSA鍵 x7 (mod143) , z103 (mod143) , に対して、適当な x(11,13 とは互いに素)な数に対して、 7 乗 したあと、 103 乗して、元の x に戻ることを確認する。

説明

バイナリー法というアルゴリズムを用いて、高速で桁溢れを起こさないアル ゴリズムを使っています。 xy z (modn) であるとき、 x 2 y z 2 (modn) x 2 y + 1 z 2 x (modn) が成り立ちます。 そこで、帰納的にべき乗を定義すると、y の二進展開に対応した処理が行われます。

DOM のアクセスは、 document のあとに、 form の名前、input の名前をそ れぞれピリオドでつなぐとアクセスできます。 そこで、結果を表示するところも名前付きの input にしておけば、表示が 楽になります。

  1. form , input のname 属性
  2. onClick 属性

kamishibai.js

Webテキストで、ボタンで画像ファイルを切り替えて出力する Kamishibai.js を紹介します。 前準備として、画像ファイル群を「共通名+通し番号+拡張子」というファイル 名で用意します。(samp1.jpg, samp2.jpg など)

kamishibai.js


function genArray(name,suf,fromnum,tonum){
    var result =[];
    for( var i = fromnum; i<=tonum; i++){
	result.push(name+i+suf);
    }
    return result;
}
var Kamishibai = function(id,files){
    this.name=id;
    this.elem=null;
    this.src="src";
    this.index=0;
    this.files = files;
    this.setSrc = function(){
	this.init();
	var prev = this.elem.getAttribute(this.src);
	if(prev != this.files[this.index]){
	    this.elem.setAttribute(this.src,this.files[this.index]);
	}
	return false;
    };
    this.resetpage = function(){
	this.index=0;
	return this.setSrc();
    };
    this.init = function(){
	if(this.elem==null){
	    this.elem=document.getElementById(this.name);
	    this.src = this.elem.localName=="object"?"data":"src";
	}
    };
    this.forward = function(){
	this.index=this.index+1<this.files.length ? this.index+1:this.files.length-1;
	return this.setSrc();
    };
    this.backword = function(){
	this.index=this.index>0? this.index-1:0;
	return this.setSrc();
    };
    this.toend = function(){
	this.index=this.files.length-1;
	return this.setSrc();
    }
    this.redraw = function(){
	this.init();
	var svg = this.elem.contentDocument;
	svg.forceRedraw();
    }
};

使い方

上記の kamishibaji.js は head 内の script で読み込んでおきます。 そして、HTML 内で図を表示したい場所に、定形の HTML を置きます。

一つの HTML で複数のこのkamishibai の機能を使うため、一つ一つオブジェ クトを生成します。 予め定めておく名前として次を用意します()。

機能名前例
オブジェクト名objname1
img タグのidobjid1
画像ファイル名の接頭語gazou
画像ファイル名の拡張子.png
画像ファイル名の連番の開始番号0
画像ファイル名の連番の終了番号9
画像ファイルの高さ100

<script>
var objname1 = new Kamishibai("objid1",genArray("gazou",".png",0,9));
</script>
<div>
<table>
<tr><td>
<img src="gazou0.png" height="100" id="objid1">
</td>
</tr>
<tr>
<td>
<button onclick="objname1.resetpage()">|&lt;</button>
<button onclick="objname1.backword()">&lt;</button>
<button onclick="objname1.forward()">&gt;</button>
<button onclick="objname1.toend()">&gt;|</button>
</td>
</tr>
</table>
</div>

例13-1

平衡木

平衡木

説明

何年も前に作ったものなので、現在の技術だと template などを使えば、もっ とシンプルにできるかも知れません。 ただ、表示させるところはなるべくプログラム生成させず、可読性とカスタ マイズを優先しました。

オブジェクトを作ることで、各ボタンを押したときに、特定の画像ファイルのみを差し替えることができる。

template


<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>template テスト</title>
<style>
    th,td {border: 1px solid black;}
</style>
</head>
<body>
<h1>テンプレートテスト</h1>
<table>
    <thead>
        <tr><th>商品番号</th><th>商品名</th><th>単価</th></tr>
    </thead>
    <tbody>
        <template id="shohin">
            <tr><td></td><td></td><td></td></tr>
        </template>
    </tbody>
</table>
<script>
    var data =[
        {"商品番号": 999001, "商品名": "リンゴ", "単価": 200},
        {"商品番号": 999002, "商品名": "みかん", "単価": 100},
        {"商品番号": 999003, "商品名": "もも", "単価": 500}
];
</script>
<script>
    var temp = document.querySelector("#shohin");
    for(var i=0; i< data.length; i++){
        var d = data[i];
        var c = temp.content.cloneNode(true);
        var t=c.querySelectorAll("td");
        t[0].textContent = d.商品番号;
        t[1].textContent = d.商品名;
        t[2].textContent = d.単価;
        temp.parentNode.appendChild(c);
    }
</script>
</body>
</html>

Interval


<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>時計</title>
</head>
<body>
<p id="tokei"></p>
<script>
setInterval(function(){
    var p=document.getElementById("tokei");
p.textContent = new Date();
},500);
</script>
</body>
</html>

Canvas


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>cambus test</title>
</head>
<body>
    <p>aaa</p>
    <canvas id="imgcanvas" width="600" height="500">
        <p>ccc</p>
    </canvas>
    <p>bbb</p>
    <script>
        var imgcanvas=document.getElementById("imgcanvas");
        if(imgcanvas.getContext) {
            var ctx=imgcanvas.getContext('2d');
            ctx.fillStyle="rgba(255,0,0,1)";
            ctx.strokeStyle="#000000";
            ctx.fillRect(0, 0, 100, 100);
            ctx.strokeRect(0, 0, 100, 100);
            ctx.fillRect(50, 50, 100, 200);
            ctx.strokeRect(80, 130, 200, 100);

            ctx.beginPath();
            ctx.moveTo(0,100);
            ctx.lineTo(200,200);
            ctx.stroke();

            ctx.font = "16pt 'Arial'";
            ctx.fillText("abc",250,50);
            ctx.strokeText("xyz",250,150);
        }
    </script>
</body>
</html>

13-3. 演習

演習13-6

与えたデータの配列に関して、折れ線グラフを書くプログラムを作れ


<script>
    var data=[3,4,2,6,10,3];
</script>

演習13-7

アナログの針を表示する時計を作成せよ

13-4. 演習の解答

演習13-6

与えたデータの配列に関して、折れ線グラフを書くプログラムを作れ


<script>
    var data=[3,4,2,6,10,3];
</script>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>折れ線グラフ</title>
</head>
<body>
    <canvas id="grahu" width="600" height="400"></canvas>
    <script>
        var data = [3, 4, 2, 6, 10, 3];
    </script>
    <script>
        var grahu = document.getElementById("grahu");
        if (grahu.getContext) {
            var ctx = grahu.getContext('2d');
            ctx.fillStyle = "rgba(255,0,0,1)";
            ctx.strokeStyle = "#000000";
            ctx.beginPath();
            ctx.moveTo(0, 100);
            for (var i = 0; i < data.length; i++) {
                ctx.lineTo(i * 100+100, 200 - data[i] * 10);
            }
            ctx.stroke();
        }
    </script>
</body>
</html>

演習13-7

アナログの針を表示する時計を作成せよ


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>時計</title>
</head>
<body>
    <p id="debug"></p>
    <canvas id="tokei" width="600" height="400"></canvas>
    <script>
        function plothari(ctx, deg, radius) {
            deg -= Math.PI / 2;
            ctx.fillStyle = "rgba(255,0,0,1)";
            ctx.strokeStyle = "#000000";
            ctx.beginPath();
            ctx.moveTo(300, 200);
            ctx.lineTo(Math.cos(deg) * radius + 300,
                Math.sin(deg) * radius + 200);
            ctx.stroke();
        }
        var tokei = document.getElementById("tokei");
        var debug = document.getElementById("debug");
        debug.textContent = "aaa" + tokei.getContext;
        if (tokei.getContext) {
            var ctx = tokei.getContext('2d');
            function tick() {
                var date = new Date();
                debug.textContent = "" + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
                ctx.clearRect(0, 0, 600, 400);
                plothari(ctx, (date.getHours() % 12) * Math.PI / 6, 100);
                plothari(ctx, date.getMinutes() * Math.PI / 30, 150);
                plothari(ctx, date.getSeconds() * Math.PI / 30, 200);
            }
            setInterval(tick, 500);
        }
    </script>
</body>
</html>

13-5. 参考文献

  1. Shelley Powers (著), 株式会社クイープ (翻訳)「JavaScriptクックブック」 オライリージャパン (2011/4/23)
  2. 加藤善規 (著), できるシリーズ編集部 (著)「できるポケット Web制作必携 HTML&CSS全事典 改訂版 HTML Living Standard & CSS3/4対応」インプレス; 改訂版 (2020/2/14)

坂本直志 <[email protected]>
東京電機大学工学部情報通信工学科