なでしこさんで文字列の二進数表現
今週も、noteの記事を書いていない状態で週末を迎えてしまった。
今週はQiitaはまあまあ早めに書けたんだけどなあ……
頭が悪いにゃあ……
頭が悪いので、今週も適当なプログラムを書いてごまかすよ。
やったこと
なでしこ で、文字列を二進数で表現 (エンコード) したり、その逆変換 (デコード) を行ったりする。
たとえば、
大石泉すき
を二進数で表現すると
11100101 10100100 10100111 11100111 10011111 10110011 11100110 10110011 10001001 11100011 10000001 10011001 11100011 10000001 10001101
となる。
プログラム
文字列二進数エンコーダ (なでしこ3貯蔵庫)
ポイント
UI作成
空のテキストエリア作成。
エンコード前エリアはそれ。
その「rows」に「5」をDOM属性設定。
その「cols」に「40」をDOM属性設定。
改行作成。
エンコードボタンは「↓エンコード」のボタン作成。
デコードボタンは「↑デコード」のボタン作成。
改行作成。
空のテキストエリア作成。
エンコード後エリアはそれ。
その「rows」に「5」をDOM属性設定。
その「cols」に「40」をDOM属性設定。
「テキストエリア作成」や「ボタン作成」などを用い、UIを用意する。
エンコード
エンコードボタンをクリックした時には
定数の入力データはエンコード前エリアのテキスト取得してURLエンコード。
定数の入力長は入力データの文字数。
定数のエンコード結果は空配列。
変数の現在位置は1。
現在位置が入力長以下の間、繰り返す
定数の現在文字は入力データで現在位置から1文字抜き出す。
現在位置を1だけ増やす。
現在文字コードとは変数。
もし、現在文字が「%」と等しいならば
入力データで現在位置から2文字抜き出す。
現在文字コードは「parseInt」を[それ, 16]でJS関数実行。
現在位置を2だけ増やす。
違えば
現在文字コードはASC(現在文字)。
ここまで。
現在文字コードの二進を8でゼロ埋めしてエンコード結果に配列追加。
ここまで。
エンコード結果を「 」で配列結合してエンコード後エリアにテキスト設定。
ここまで。
まず、エンコードする文字列を取得する。
文字列を取得したら、「URLエンコード」を用いて文字列の UTF-8 表現を取得する準備をする。
URLエンコードを行うことで、ASCII で表現可能な文字のみがそのまま残り、残らない文字は % に続いて十六進数 2 桁を書くことで表される。
そこで、% があったらその次の十六進数を読み取り、それ以外の文字があったらその文字コードを取得することで、文字列の UTF-8 表現を取得できる。
URLエンコードをしたら、実際にこの方法で各バイトの値を取得する。
このとき、なでしこの文字列内の位置の指定は 1-origin であることに注意する。
バイトの値を取得する際、十六進数や二進数 (デコードで使用) から数値に変換する命令は見つからなかったので、「JS関数実行」で parseInt を実行することで変換することにした。
(「整数変換」の中身は parseInt であり、入力文字列に 0x をつけることで十六進数からの変換はできるが、二進数からの変換は難しそうである)
各バイトの値を取得したら、それを二進数に変換する。
「二進」で二進数に変換したあと、「ゼロ埋」を用いて 8 桁での表現に統一する。
最後に、変換した二進数を「配列追加」で配列に格納しておき、「配列結合」で空白区切りのひとつながりの文字列に変換して出力する。
デコード
●(Vを)要素デコードとは
「parseInt」を[V, 2]でJS関数実行。
それを16進数変換して2でゼロ埋め。
「%{それ}」を戻す。
ここまで。
二進数の文字列を受け取り、それをURLエンコードされたバイトの表現に変換する。
エンコードのときと同様に、進数を指定して文字列を数値に変換できる parseInt や、桁数を統一できる「ゼロ埋」を用いている。
デコードボタンをクリックした時には
エンコード後エリアのテキスト取得。
それの「/[^01]/g」を空に正規表現置換。
それの『/(.{8})/g』を「$1 」に正規表現置換。
それの右トリムを「 」で区切る。
それに{関数}要素デコードを配列関数適用して配列只結合。
それをURLデコードしてエンコード前エリアにテキスト設定。
ここまで。
空白の扱いはいくつか考えられるが、今回は「(空白を含む) 0 と 1 以外の文字をすべて無視し、強制的に 8 桁ずつに区切ってデコードする」ことにした。
これにより、今回のプログラムで出力する 8 桁ずつ区切られた表現だけでなく、4 桁ずつ区切られた表現などにも対応できる。
一方、誤って途中で 1 桁抜けてしまうと、それ以降がすべてずれてしまい、すべて誤ったデコード結果になってしまう。
まず、「正規表現置換」を用いて、この「強制的に 8 桁ずつに区切る」処理を行う。
このとき、「」を用いて文字列を表すと正規表現で指定回数の繰り返しを表す {} がなでしこの変数展開と解釈されてしまい、処理に失敗するので、『』を用いて表す。
置換を行ったあと、「右トリム」により最後の余計な空白を削除する。
8 桁ずつに区切られた文字列に変換したら、それを「区切」でそれぞれのバイトの情報が各要素に格納された配列に変換する。
さらに、「配列関数適用」を用いてこれらを URL エンコードされたバイトの表現に変換し、「配列只結合」を用いて1 個の文字列にする。
最後に、「URLデコード」を用い、二進数で表されていたもとの文字列を得る。
まとめ
なでしこを用いて、文字列を二進数で現したり、二進数で表された文字列をもとの文字列に戻したりする処理を実装できた。
コメント