データ活用に欠かせないのはつなぐこと。複数のデータを比較し、組み合わせて、新たな知見を生まれます。

その足かせとなるのはデータ形式の不一致。数と一言で言っても半角全角、カンマ区切りの有無、小数を含むかどうか、万など漢数字表記の有無など、個性豊かな様々なデータ達・・・。

もちろんコンピューターなので、様々な表記方法を想定して対応することは可能ですが、網羅性を保証できず、膨大なデータ量に対する処理では何十倍ものコストとして跳ね返ります。 同じ手間ならデータを作る際にかけるのが効率的です。

どうデータ形式の定義するか?ベストはリソース記述フレームワーク(RDF)の語彙を使うことでしょう。 Googleの検索エンジン他で使用されるスキーマオルグ(schema.org)や、Facebookが提唱し一般化したオープングラフプロトコル(OGP)、日本政府が提唱する共通語彙基盤もその一種です。

語彙でつながるオープンデータを、LOD(エルオーディー/Linked Open Data)、5つ星オープンデータと呼びます。

5つ星オープンデータ/LOD 3基準

1. リソースとデータ項目(語彙)をURLで表現する
IDではなくURL。アクセス可能なURLを使用する。
自分のリソースのURLは、自分で編集可能なドメインを用いる。

2. 共通の語彙の利用
語彙は正しく、できるだけ既存の語彙を使う。(schma.org/url)

3. 外部リンク
できるだけ外部リソースへのリンクを含める。(SNSやWikidataへのリンク)

ただ、まだまだRDFへの理解が浸透していないため、まだちゃんとしたデータは多くはありません。よりシンプルに作りやすくするためのツール整備を進めました。


NQuads.js
語彙を含んだLODのJSON表現、JSON-LDを扱うライブラリjsonld-esを、Node.js用のライブラリjsonld.jsから移植。 依存ライブラリを次々と全部ESモジュール化して、GitHub Pagesとして公開。 require表記をgithub.ioを使ったURL importに書き換えたので、全ソース、ブラウザでも使用可能になりました。ESモジュールはDenoモジュールとしても使えるので、Denoでサクサク活用可能です!

NQuads.jsは、LODのテキスト表現「N-Quads」をJSONLD.jsを使って作成。 import { JSONLD } from "https://taisukef.github.io/jsonld-es/JSONLD.js"; class NQuads { static async parse(s) { return JSONLD.fromRDF(s, { format: "application/n-quads" }); } static async stringify(json) { return JSONLD.toRDF(json, { format: "application/n-quads" }); } } export { NQuads }; コアはこれだけ。JSONLDをimportして使うだけのライブラリなのでとってもシンプル!
ちゃんとしたオープンデータを増やしましょう!


データ活用はじめのいっぽ、コンピューターとプログラミングへの入り口、IchigoJamのファームウェアの不具合修正
- ichigojam-1.4b29.zip
OUT11,0が効かない不具合修正(OUT11、IN4を出力に切り替えて使う場合の番号です)


福井県独自の緊急事態宣言最終日、ランチは通常営業だった鯖江駅前商店会」でタコライス!

jigインターン2021夏第一シーズン2日目、今日から本格開発スタート。5チーム、バリバリと作り始めています。 技術的な質問はSlackや、Zoomで常時受け付けます。 一人で5分悩んだらチームに相談、それでも5分で解決しないなら呼んでもらう感じで進めます。 どうにもハマって抜け出せない、そんな経験がプログラミングを止めてしまう理由になっている?


jigインターンのみなさん、進捗どうですかー?

勉強会での経験を元に、フロントエンド、バックエンド、それぞれ分担しての開発。JSON(ジェイソン)でハマったという声があったので、少し解説。

JSONとは、JavaScript Object Notationの略で、JavaScriptのオブジェクトの表記方法を元に作られたテキストベースのフォーマットです。 同じテキストベースのフォーマット、XMLと違って仕様がシンプルで人間にも読みやすいのが特徴です。

CSVとの違いは階層構造の表現ができるところ。入れ子になっているデータ構造も表現可能です。逆に、入れ子がなく、ほぼ同じ項目がずらっと並ぶ配列はCSVにした方が軽くて、Excelなど表計算ソフトなどで開きやすくなります。 CSVで表現できるものはすべてJSONで表現できます。(CSV.jsを使えばJSONとの相互変換は簡単!)

ハマりやすいポイント1。JavaScript内での表記とちょっと違う。
{ name: "jig", value: 2021, } この表記方法、JavaScriptとしてはOKですが、JSONとしてはNGです。
正しくは、こちら { "name": "jig", "value": 2021 } 微妙な違いがありますね。項目名は必ずダブルクォートで囲む必要があり、最後の項目後にコンマがあってはいけません。
JSONの方が厳格なので、JSONフォーマットはJavaScriptではそのまま使えます。

JavaScriptオブジェクトとJSONの相互変換。
JavaScriptオブジェクト → JSON
console.log(JSON.stringify(json)); 下記のようにパラメータを付けると、改行とインデントを付けて、テキストファイルとして読みやすくできます(ファイルサイズは増える) await Deno.writeTextFile("test.json", JSON.stringify(json, null, 2)); JSON → JavaScriptオブジェクト
console.log(JSON.parse('{"name": "jig", "value": 2021 }')); ファイルから読み込む時はこちら console.log(JSON.parse(await Deno.readTextFile("test.json")));

ハマりやすいポイント2。文字列になることを忘れずに!
下記のように日時を表すデータをJSONにすると・・・ $ deno > JSON.stringify({ date: new Date() })) '{"date":"2021-08-17T23:17:16.916Z"}' このように自動的に何らかの文字列になります。(new Date().toString()したものとも違うので注意)
元のDateオブジェクトとして使いたい場合、new Date("2021-08-17T23:17:16.916Z") などと再度オブジェクトを生成する必要があります。

大きくても小さくても、気軽に保存したり送ったりできるJSON、楽しく使っていきましょう!

情報セキュリティ好きもいる、jigインターン2021夏。掲示板といえばどう荒らし対策をするかが気になりますよね! 電子署名(HANKO)を使った対策も、今風でおもしろいかもしれません。

HANKOsrc on GitHub
前回はEd25519のWebAssembly版で作ったHANKOを、AES-GCMで使ったオープンソースforge内のed25519.jsを使って再実装。

HANKO_ID: ea687927de2d824363b2b1cbc62d1c42ab7a0bd79d26574b816b4f60c05d1e36
メッセージ: jigインターン2021夏、スタート
電子署名: 2719b28c34e89d9c843799d12f022a4216af0b078c477505e7ff3335b4ae1f7c1b4c51c13d551ebbcc691eae38d0c7c7d4094791010a56badcf3b8653b0af006

こちら入れると検証できます。メッセージなどに少しでも改竄あれば、検証に失敗します。

使用したライブラリ、forge-es(src on GitHub)に、ECCを使った鍵共有ECDHもあれば完璧なんだけど・・・。

電子署名はネット時代のハンコ!原理は難解な数学でややこしいですが、使うのはシンプル。いろいろ遊んで学ぶ、情報セキュリティ。

2日目のjigインターンブログ、5チーム分、更新されてます!
⭐jigintern diary⭐

いよいよ開幕、jigインターン2021夏、昨年に続きコロナ仕様でオンライン。同時最多の20名!

お楽しみjigBOXの開封後、恒例のメガネ堅パン記念写真。


盛り上がったオンラインアイスブレイクの新企画、チーム毎に分かれての家のモノでつなげるしりとりチャレンジ。制限時間5分。Dチームが15コで優勝!

テーマ別ブレイクアウトルームと合わせたランチタイムの後は、勉強会!


JavaScript (Deno) でつくる超かんたんwebアプリ入門
2時間枠、Denoのインストール、JavaScriptを使ったサーバーサイドプログラム、ブラウザで動くフロントエンドプログラムの基本をざっとハンズオンで伝授。全員動きました!

つまづき勝ちな環境構築。Denoのインストールした後、「deno」コマンドで動かない時は。環境変数のPATH(パス)を設定します。
Windowsの場合、PowerShell(VSCodeのTerminal、または、ファイル名を指定して実行 powershell)で、下記コマンドの「fukuno」を自分のコンピューターでのユーザー名に変更して実行

$ENV:Path="/Users/fukuno/.deno/bin/;"+$ENV:Path

Macの場合はこちら(同じく「fukuno」を自分のユーザー名に変更)

echo "export DENO_INSTALL="/Users/fukuno/.deno"" >> ~/.zshrc echo "export PATH="\$DENO_INSTALL/bin:\$PATH"" >> ~/.zshrc

チーム開発とスクラム、ファイル管理のGitHubに関して基本を押さえ、アイデア出しからのチーム開発開始!

各チーム、アイデアが出揃ったところで、プロダクトバックログ(優先順位付きの作るものリスト)を作って、タスクに分割。具体的な技術的な質問が出始めました。

円滑なチーム開発に必須な、プログラムのファイル分割。JavaScriptではこのようにします。
例として、パラメータを2つとって足し算する関数 add を含む、ファイル add.js を作ります。 const add = (param1, param2) => { return param1 + param2; }; 関数addを他のファイルから呼び出せるようにするために export を追加します export { add }; 試しに呼び出してみる test.js を作ってみます。(ローカルなファイルは ./ で始める必要あり) import { add } from "./add.js"; console.log(add(1, 2)); 動かす時は deno run

$ deno run test.js

複数の関数をexport/importしたい場合は、export { add, sub, mul } と増やせばok。必要なものだけimportすればいいので、import { add, sub } と書けます。 import/exportを使ったJavaScriptのプログラムをESモジュールと呼びます。

一見大きな課題も、分割して、分担して、それぞれ作って組み合わせたら、自分ひとりではなし得ないモノができますよ!


E2EEメッセージングヘルパーsrc on GitHub
PureなESモジュールによるE2EE実装。ECDHを使った鍵共有から、もう一歩進めてAES-GCMによる暗号化復号化にも対応。 AES-GCM-esのプログラムから、ForgeをforkしてESモジュール化したforge-esをimportしている様子などチェックしてみましょう。

こちら、キーペア生成、相手の公開鍵を受け取った鍵共有、暗号化、復号化の実装です。
generatebutton.onclick = async () => { const keypair = ECDH.generateKeys(curve); ecdhpublickey.value = keypair.publicKey.buffer.toString("hex"); ecdhprivatekey.value = keypair.privateKey.buffer.toString("hex"); }; generatebutton2.onclick = async () => { const privateKey = ECDH.PrivateKey.fromBuffer(curve, Buffer.from(ecdhprivatekey.value, "hex")); const peerPublicKey = ECDH.PublicKey.fromBuffer(curve, Buffer.from(ecdhpublickey2.value, "hex")); const secretKey = privateKey.deriveSharedSecret(peerPublicKey); ecdhsecretkey.value = hex.fromBin(secretKey); iv = AESGCM.createIV(); }; encryptbutton.onclick = async () => { const data = new TextEncoder().encode(ecdhmessage.value); const key = hex.toBin(ecdhsecretkey.value); AESGCM.incrementIV(iv); const [encdata, tag] = AESGCM.encrypt(key, iv, data); ecdhciphertext.value = hex.fromBin(iv) + "_" + hex.fromBin(encdata) + "_" + hex.fromBin(tag); }; decryptbutton.onclick = async () => { const key = hex.toBin(ecdhsecretkey.value); const [iv, encdata, tag] = ecdhciphertext.value.split("_").map(h => hex.toBin(h)); const data = AESGCM.decrypt(key, iv, encdata, tag); if (data) { ecdhmessage.value = new TextDecoder().decode(data); } else { ecdhmessage.value = "復号失敗"; } }; 共通鍵を使った安全な暗号化と言われるAES-GCMですが、鍵と合わせて使用するIV(初期化ベクトル)の使い方を間違うと第三者が復号できてしまいます。 上記ではIVはランダムに生成し、暗号化のたびにインクリメントする形で実装しています。 (参考、本当は怖いAES-GCMの話 - ぼちぼち日記

情報セキュリティに興味が出てきたら、中高生のためのサイバーセキュリティコンテスト「CyberSakura / サイバーサクラ」への参加、応援もご検討ください!

jigインターンによるレポート「⭐jigintern diary⭐」もスタート。各チーム、交代で毎日1名ずつアップ、最終日には全員による統括ふりかえりが公開されます。 お楽しみに!

安全安心を実現する偉大な発明、公開鍵暗号、現在主流の楕円曲線暗号をブラックボックスなしのオープンソースで実現してみました。 ブラウザとDenoで動きます。


公開鍵暗号は、人に見られても良い公開鍵と、人に見られてはいけない秘密鍵の2つの鍵、キーペアを使うのが特徴です。 通信する相手の公開鍵と、自分の秘密鍵から一時的な共通鍵をお互い生成します。この時、共通鍵は一切ネットワークに流れていないことがポイントです。 経路中でデータを傍受されても鍵が分からないため解読できません。


E2EEメッセージングヘルパー
実際動かしてみましょう。2つのブラウザでキーペアを生成し、お互いの公開鍵をもらって、共通鍵を生成してみると、同じものが表示されることが分かります。


taisukef/ECDH-es: JavaScript ES module for ECDH and ECDSA for browsers and Deno
前バージョンのものと違ってWeb Cripto APIはほとんど使用していない、Pure JavaScriptバージョンとなっています。 ブラックボックスは少ない方が安全です。 唯一使っているのは、安全な疑似乱数を取得するCrypto.getRandomValues()ですが、この実装もより安全なものに変更したり、安全性を検証するのもいいですね。

AES-GCM-esを準備して、暗号化復号化にも対応しました)

links
- 賛否両論!? E2EEメッセージングヘルパー、エンドツーエンド暗号化webアプリを作ってみた
- 見られても大丈夫な暗号鍵!? webアプリでECDH(楕円曲線ディフィー・ヘルマン)鍵共有実験

勝山市、中学生自身が開発する校内SNSによる学校DX by PCN勝山片瀬クラブ!
校内版SNS 中学生開発へ 勝山南部 つぶやき、画像 瞬時に閲覧:日刊県民福井Web
URLインポートでESモジュールを使っていので、JavaScript / Denoですね!

IchigoJamでプログラミングの基本が分かったら、JavaScriptで遊ぶのがオススメです。ゲームやツールづくりからAI、画像処理、音声、動画まで、幅広く楽しめます。

IchigoJamで扱える記憶容量はせいぜい100KB、現代のPCのHDDはTB単位なので、ざっと1000万倍もの巨大容量が自由自在!?

とはいえ、メインメモリはGB単位なので、1GBのファイルでさえExcelで開けません。そんなときはプログラミング!行単位で分割された大容量ファイルを扱うライブラリ「line-rw」を作り、CSVReader/CSVWriterを提供する「csv-rw」と、NDJSONに行単位アクセスを追加しました。


line-rw
readLine、writeLineと行単位でアクセスします。非同期関数なので、読み込み終了を待ってほしいときは await 付きで呼び出しましょう。 読み込みバッファを超えて改行を探すところで一工夫していますが、もうちょっと改善の余地があります。


csv-rw
上記 LineReader / LineWriterをそれぞれ使ったCSVReader / CSVWriterです。 CSVはダブルクォートを使って改行付きのデータを入れられるので、1行読んで途中なら更にもう1行読む感じで1レコード取得しています。


NDJSON
ワクチン接種数オープンデータで使われているNDJSONもLineReaderで真価を発揮! CSVと比べて容量は大きくなりがちですが、1行目を読む必要がなく項目が変化しても大丈夫な柔軟なデータ形式です。

ESモジュールなので、インポートすれば即使えます。 関数を足したい、更に効率を上げたいなどの場合にも、GitHubからcloneして改造できるオープンソース。 それぞれ試しに動かせる example、deno test -A でチェックできる、test ディレクトリを付けています。

・・・改行コードの問題を忘れていました。Windowsで要確認です。
そろそろ改行はLF(=10)のみ統一したい。

キャラクターも仕様もキュートなJavaScriptランタイム「Deno」の新バージョン1.12で、WebSocketもネイティブ実装に対応とのことで、実験しました。

websock_test_chat on GitHub
クローンして、サーバー、クライアント2つ、計3つのターミナル上で動かしてみることができます。

Denoで、promptメソッドを使うとコンソールでの文字入力ができますが、他のスレッドは一切停止することに注意。 sleepを使って、送受信処理する時間を設けてます。

IPv6に対応するサーバーにするためには、hostnameを"::"と設定するのがポイント。 const port = 8081; const hostname = "::"; const listener = Deno.listen({ port, hostname });

wsclientにある接続先ホスト名を変更して、遠隔からのリアルタイム送受信ができる感を味わってみましょう!

Deno 1.13 で、ネイティブサーバーが --unstable オプションなしで動くようにする予定とのことで、楽しみです。

links
- https://zenn.dev/magurotuna/articles/deno-release-note-1-12-0Deno 1.12.0 がリリースされたので新機能や変更点の紹介
- deno/Releases.md at main · denoland/deno

文字情報基盤に縮退マップのデータを変換して追加し、より探しやすくなりました。

漢字検索、異体字検索 - 福」たくさんの福!

縮退とは6万の漢字を表現できない環境向けに代替漢字へと変換すること。ユニコード前提な現代ではあいまい検索など、正規化に使うと良さそうです。

文字情報基盤 MJ縮退デモ
難解な漢字をいれると適度にやさしい漢字になります。


縮退マップの利用ガイドにおもしろいことが書いてあります。読みも意味も不明な漢字が400字もあるそうです。


漢字検索、異体字検索 - 秀丸
福井高専の先輩、斉藤秀夫さん開発の有名ソフトウェア「秀丸エディタ」はなんと漢字にもなっていた!?

ここで問題です、JavaScript でこの難解文字 "𤔜㙒𡙌𡗟".length を表示するとどうなるでしょう?

正解は、7!

見た目は4文字なのに不思議ですね。
ユニコードの仕様で異体字セレクタ(IVS)は2つのコードポイントで表現させるので、1つの文字を表現するために2つのJavaScript文字を使っています。

この仕様のせいでJavaScriptの文字列はややこしいことになっているので改善しましょう。 普通の文字列関数、charAtやcodePointAtでは中途半端なコードにしかならなかったり、indexOfの数がずれてしまったりするので、新たに Str.js を作りました。

import { Str } from "https://code4fukui.github.io/mojikiban/Str.js"; console.log(new Str("𤔜㙒𡙌𡗟").length); // 4

見た目と一致する文字は、書記素(グラフィーム)と言います。以前結合絵文字を扱うときに使った GraphemeSplitter を内部に使っています。

Code for Fukui によるオープンソースプロジェクト。社会OS開発、ぜひご一緒に!
code4fukui/mojikiban src on GitHub

先日発表された「ベースレジストリの指定について」で、即効性ありと区分されているデータに「文字情報基盤」がありました。 「漢字」は、日本での文字コミュニケーションの基本です。デジタルで表現できない文字があるとつらいですね。

いろいろな方の尽力により、日本で使われている漢字ほぼすべて、58,862コの漢字がユニコードで表せるようになっています!スゴイ!


漢字検索、異体字検索src on GitHub
こちらで「よみ」と「漢字」から検索できるようにしました。WebFontもありますが、30MBもあるので、58,862コGitHub Pagesに生成した画像データ(mj)を用意して使っています。

Code for Fukui によるオープンソースプロジェクト。低レイヤーから作る社会OS。ぜひご一緒に!
code4fukui/mojikiban src on GitHub

全国19万あったまち(=町字)ですが、本当のところいくつあるか不明な様子。
ベース・レジストリとしての住所・所在地マスターデータ整備について

地方自治法に「町若しくは字」、住居表示に関する法律に「町又は字」と表現されているが、地方自治法にも住居表示に関する法律にもこれら町字の定義は存在しない。

日本DXはじめのいっぽ、住所をまずはちゃんと定義したいですね。全国ざくっと用意して、各自治体でオーサライズがされればできあがりです。マスターデータ案に記載されている英語表記が気になりました。外国の方向けにひとまずアルファベットでの表記は欲しいですね。 あとは、まちの「よみ」のデータを見つければ、ひとまず自動変換できそうです。


固有名詞のかなローマ字変換
行政基本情報データ連携モデル 住所」に英語表記に関する記載があったので、それに代替準拠する「かなローマ字ライブラリ、Romaji.js」を作りました。 以前作成した Moji.mjs も使って、カタカナや半角にも対応したサンプルアプリも合わせて提供しています。


ヘボン式のローマ字は「観光立国実現に向けた多言語対応の改善・強化のためのガイドライン」にある表をCSV化した「ヘボン式ローマ字.csv」を作成して、使っています(make_json.js)。

低レイヤーからの地味な積み上げが大事な都市OSづくり!

表形式のデータの保存にはCSVが便利です。誰でもプレビュー、テキストエディタ、表計算ソフト、Google Docsなど、様々なツールで開くことができます。

ただ、文字化けやヘッダーの無いデータ、無駄な空行があるデータなど、おかしなデータが多いため、好きになれないプログラマーも多いことでしょう。


そこで作りました、厳格なCSV、StrictCSV!

日本の19万のまち、TownIDのCSV all.csv をStrictCSV all.s.csv に変換すると45%ファイルサイズが削減できました。(9.3MB→5.0MB、gzip後で 1.6MB→1.3MB 14%削減)

- StrictCSV 書式
拡張子は .s.csv
文字コードはBOM付きUTF-8
改行コードはLF
ヘッダー行は必須
レコード0件を許容する
ダブルクォート、コンマ、改行を含める場合はダブルクォートで囲む(ダブルクォートは2つにする)
存在しないフィールドは前行以前に存在したフィールドが省略されたものとする

ついでに、データ項目が少ないときは前行以前に登場したコードが省略されたことにするルールをいれたことで、同じ都道府県名や市区町村名がずらっと続くデータをシンプルにできます。


StrictCSV on GitHub / Code for Fukui
まだ実装はESモジュール対応のJavaScriptのみ。お好きな言語でご実装、ご貢献ください!

import { StrictCSV } from "https://code4fukui.github.io/StrictCSV/js/StrictCSV.js"; const data = await StrictCSV.load("test.s.csv") || [{ name: "a", val: 1 }, { name: "b", val: 1 }]; const s = StrictCSV.stringify(data); console.log(s); const data2 = StrictCSV.parse(s); console.log(data2);

Denoやブラウザで動きます。

* 改行コードは現在MacOS/LinuxがLF、WindowsがCRLFです。古いMacOS9がCRだったことから、Windowsが間をとってCRLFにしたようですが、WindowsもLinux化が進む今、人類としての改行コードはLFでいいでしょう。
由来がはっきりしないWindowsの“謎”仕様──Windowsの雑学(諸説あります)

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / RSS