技術は記憶の彼方へと

覚えたつもりですぐに忘れるエンジニアの備忘録

ファイルのエンコード情報が知りたい

長らく期間が開いてしまいました。
気が付けばプライベートでプログラムを書く機会がめっきりなくなってしまっていたので、久しぶりにリハビリがてら簡単なプログラミングでもやってみましょう。
なかなか時間が取れないので、今回はシンプルなものを作ります。

目次


今回作るもの


今回作っていくのは、タイトル通り、ファイルのエンコード情報を知るためのプログラム。
ファイルオープンエラーとかでよくあるエラーにエンコーディング情報の不一致によるオープンエラーが発生します。
唐突に出てきて面倒なんですよね。適当に調整して無理やり合わせてもいいけれど、それはそれでエラー吐きまくりで気分が悪い。
そんな思いで、作るかって思いました。できれば、Linuxのfile関数みたいなものを作りたいけれど、そこに追加機能としてこいつを組み込んでいきたい。

そもそもエンコーディングってなんだ


そんなもん知ってるわ!!!って方はスルーして本題に進んでください。
あくまで念のための説明枠ですので。

「データを一定の規則に従って、目的に応じた情報に変換すること。」
ざっくりいうとこういうことです。
この記事は日本語で書かれています。日本語を勉強した人とか、日本人とかなら読めますよね?たぶん。
ただ、コンピュータはどうでしょうか。エンコーディングされてなかったら多分読めません。
この駄文がどんな規則に則って書かれてるのか判断がつかない為です。
そんな時にエンコーディングが役に立ってきます。
このデータは「ASCII」という規則で書かれてます。とか「UTF-8」の規則です。とかわかればコンピュータもどの方式で処理していけばいいかわかるので、文章の処理ができそうですね。
文字化けとかがよくある例ですね。処理方法がわかってなくて、自分の知ってるやり方で無理やりやった結果ですね。
「譁?ュ怜喧縺代?繧オ繝ウ繝励Ν繝?く繧ケ繝医→縺ェ繧翫∪縺」こんな感じのやつです。
これはわざと作りましたが、文字化けテスター - instant tools というサイトで、「文字化けのサンプルテキストとなります」と入力しました。UTF-8をShift-JISで開こうとした結果のようです。
プログラムとかでファイルオープンとかすると、こんなの読めないってエラーになるよくあるやつです。
まぁ、この化けた文字になってしまうとなんて書いてるか読めないですよね。。。

本題


駄文つらつら書くのはこの辺に、そろそろ本題に入りましょう。
エンコーディングの問題を解決したかったら、そのファイルがどの形式で作られているのか知ればいい。
ということで、Python使ってサクッとエンコードが何でできてるのか見ていきましょう。
今回は、外部ライブラリである「chardet (https://chardet.readthedocs.io/en/latest/)」を使っていきます。
外部ライブラリなので、pip使って入れていきます。
ちょくちょく私の環境ではpipが古いって文句言われるので、更新しておきましょう。

 $ python3 -m pip install --upgrade pip

更新したら、pip経由でライブラリをインストールします。コマンドはシンプルですね。

 $ pip install chardet 

install出来たら使っていきます。
こいつはライブラリ単体でもインタプリタ上で動作しますが、今回はソースに組み込んで確認していきます。

ファイルを引数に与えて読み込ませる簡単なプログラムを作っていきます。

import chardet
import sys

引数を扱うので、標準ライブラリのsys.argvでも使いましょうか。この辺りは完全に好みです。今回はシンプルにやりたいので...
sys.argvを使うため、chardetとsysをインポートします。
ファイルが何件来るかわからないですね...対応できるように作りましょう。
引数が入ってなかったことも考慮に入れて、引数ないよってメッセージも入れて、できたのがこんな感じ。

import chardet
import sys

val = sys.argv

if len(val) > 1 :
    for arg in val:
        if arg != "encoding.py":
            print(arg)
            with open(arg,'rb') as f:
                print(chardet.detect( f.read() ) )
else:
    print("No argument is set, so no information can be retrieved. You need to specify the file you want to look up as an argument.")

encoding.pyとでも名付けてざっくりとこんな感じ。
sys.argvで引数情報をvalに入れて、引数にファイルがあるかをifで判断してます。
あとは、valに引数がある限りForループで回すシンプル設計です。
sys.argvを使ってる関係上、上記コードを端末上で呼び出すと、以下コマンドになるわけですが...

 $ python3 encoding.py FILE1 FILE2 ... FILEn

LISTとして得られる値が、

 ["encoding.py" "FILE1" "FILE2" ... "FILEn"]

といった感じに、ソース名も引数に入ってしまうので、ifのNot equalで弾いてます。
実際に動かしてみるとこんな動作になります。

$ python3 encoding.py ansi_sample.txt shif-jis_sample.txt utf-8_sample.txt
ansi_sample.txt
{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
shif-jis_sample.txt
{'encoding': 'SHIFT_JIS', 'confidence': 0.99, 'language': 'Japanese'}
utf-8_sample.txt
{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

sampleに使ってるテキストは、名前にエンコードを合わせて適当に作ったファイルですがちゃんと判別できてそうですね。
これの得られた結果を返せたらなんかそれっぽいのできそうですね。
あとは、このchardetはウェブページのエンコードも見れるので、その辺もちょっとやってみましょう。

import urllib.request
import chardet

rawdata = urllib.request.urlopen("https://www.google.com/").read()
print('https://www.google.com/')
print(chardet.detect(rawdata))

rawdata = urllib.request.urlopen("https://hatenablog.com/").read()
print('https://hatenablog.com/')
print(chardet.detect(rawdata))

ざっくり、天下のGoogle様とこのブログの大本はてな様のページハードコーディングしてみました。さて、結果は?

https://www.google.com/
{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
https://hatenablog.com/
{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

こんな感じで取れました。これはこれで、色々使えそうですね。スクレイピングとか。

最後に


今回はそんな時間も取れないので、シンプルなものを作って遊んでみました。
まぁ、思っていたより情報はとれてそうですね。
久々のプログラムなので、こんな感じの簡単なコード書くのもリハビリにはいいかもしれないですね。
ちょっとづつ触れていかないと忘れてしまうので、できれば時間作ってソース書いていかないとなぁなんて思うこの頃です。
そんなこんなでのんびりプログラムなんか書きながら、今回はこの辺で。

【Git】GitHubにssh keyを登録する -備忘録

日々を仕事に追われ、個人的にプログラム作成などができておらず更新ができていませんでした。
そんな状態だったので、リハビリを兼ねて少しずつプログラミングも進めていけたらなぁと思いつつ、久々にGitに触れました。
久々すぎてアカウント忘れて、アカウント作成しなおして1からのスタートです。
コンソールでのGit操作にはアクセストークンが必要なので、今回はssh keyを使っていく事として登録までやります。

目次

鍵を作成する


ターミナル(Windowsではコマンドプロンプト)を起動します。
起動後、以下のコマンドを入力します。
(your_email@example.comはGitアカウントとして登録しているE-Mailアドレスに変更してください。)

$ ssh-keygen -t ed25519 -C "your_email@example.com"

上記ではED25519というアルゴリズムを用いてキーペアの作成を行っていますが、利用しているシステムによってはサポートされておらず失敗する事があります。
その場合には以下のコマンドを試してみてください。

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

これらのコマンドを打ったら何か聞かれると思います。それぞれEnter押下で問題ないですが、何を言われてるのかだけ以下に記しておきます。(ED25519のアルゴリズムで生成させています。)

Generating public/private ed25519 key pair.

公開鍵/秘密鍵のペアをed25519のアルゴリズムで作成する。

Enter file in which to save the key (C:\Users\user/.ssh/id_ed25519):

鍵を保存するファイルを入力してください。
私の環境のデフォルトではC:\Users\user/.ssh/id_ed25519となっています。
変更したい場合はここで入力してからEnter、変更しない場合はそのままEnterを押下すればデフォルトで作成されます。

Enter passphrase (empty for no passphrase):

パスフレーズを入力してください。
パスフレーズを設定する場合は入力してEnterを、設定しない場合はそのままEnterを押下します。

Enter same passphrase again:

設定したパスフレーズを再度入力してください。
先ほど設定した場合もしなかった場合も確認の為、聞かれます。
設定した場合は設定したパスフレーズを入力してEnter、していない場合はそのままEnterを押下します。
出来上がった鍵は2種類あり、秘密鍵と公開鍵になります。
名前の通り、秘密鍵は自分だけが持つ鍵で鍵の中身の情報は絶対に誰にも公開してはいけません
私の場合デフォルトで、id_ed25519とid_ed25519.pubという名前で鍵が作成されましたが、末尾に「.pub」とついているものが公開鍵です。

作成した鍵をGitHubにアップする


先ほど作成した鍵を、GitHubにアップします。

https://github.com/settings/ssh

上記リンクから、公開鍵の設定を行います。
f:id:Cloudvelse:20211108141344p:plain
こんな表記があると思いますので、New SSH keyをクリックします。(Addとなっているかもしれません。)
f:id:Cloudvelse:20211108141610p:plain   上記のような画面に遷移します。
Titleに鍵の名前、Keyに鍵の中身を入力します。
鍵の名前は任意の名前にすれば問題ありません。
鍵の中身については、以下のコマンドでクリップボードにコピーすると便利です。
Windowsの場合

$ clip < .ssh\id_ed25519.pub

Macの場合

$ pbcopy < ~/.ssh/id_ed25519.pub

でコピーして、Keyのところにペーストします。
(.ssh\id_ed25519.pubの部分は上記の鍵を作成するで作成した鍵の名前になります)
最後に、下のAdd SHH keyを押下すれば、鍵が登録されます。

確認


うまく接続できるかの確認をしておきましょう。
以下のコマンドをターミナル上で入力します。

$ ssh -T git@github.com

成功すれば以下のようなメッセージが帰ってきます。

Hi (GitHub UserName)! You've successfully authenticated, but GitHub does not provide shell access.

うまくいかなかった場合、

Error: Permission denied (publickey) - GitHub Docs

GitHubの公式ドキュメントが役に立つかもしれません。
入力のミスの可能性もありますので、それらを確認して、ダメそうなら一度GitHubに登録した鍵を削除し、上記手順で再度試してみるとうまくいくこともあります。

最後に


今回は、GitHubをコンソールで扱えるようにするための準備を行いました。
久々だったこともあって少し時間がかかりましたが、問題なく扱えるようになったかと思います。
あくまで備忘録として残してるだけなので、わかりずらいところもあるかとは思いますが、何かの役に立てば幸いです。
そういえば、私は無料ユーザなのでPrivateリポジトリの数に制限があったように思ってましたが、制限がなくなってますね。
使い勝手がよくなってるのでありがたいです。
それでは、今回はこの辺で。

【Linux】Debian系ディストリビューションのパッケージ管理コマンドの違い

Linux多少できるよね?確か個人用にLinuxマシン持ってるとか言ってたもんね?なんて言われてお仕事依頼されました。
ディストリビューションによってそれぞれ個性があってコマンドが若干違うことは周知の事実。
ディストリビューションを聞いたらUbuntuだとのこと。やったことないんですよね...
普段のマシンはFedoraだし、レンタルサーバも借りてるけどこれまたFedora。好きなの。
CentOSも触ったことあったけど、Debian系はもしかしたらはじめまして?って感じです。
そして、最初に思ったこと。パッケージ管理でdnfが使えない。じゃあyum
yumでもない...調べたらなんか3つくらい出てきた...なんでこんなにあるのさ
ということで本題

目次


apt-get


調べてるサイトの中では圧倒的に多く見かけた子。
Debianプロジェクトが開発したパッケージ管理システム。パッケージのダウンロード、インストールと依存関係があるパッケージの自動取得とアップデートもできる子。
もともとはtar.gzで圧縮されたアーカイブファイルからソースを持ってきてコンパイルすることが当たり前だった時代にアップデートのたびにコンパイルだの整合性だのっていうのは大変だった。
これの管理システムが必要だってことでdpkgコマンドを作って、これを管理するために「Advanced Packaging Tool(通称APT)」が作られ、これのコマンドがapt-getらしい。

うん、わからん。
まぁ、大変だったから楽するためのツール作って、そいつを管理しようってことなんだろう。 だが、この子はUbuntu14.04からは非推奨になったらしい。(現在の最新は長期サポート版の20.04LTS)

apt


先ほどのapt-getとapt-cache(主にパッケージ情報の探索をするもの)を統合し、aptコマンド一つで完結するようになったもの。
14.04から推奨されているコマンドで2014年4月1日からリリースされたAPTができてから16年たってリリースされた新星。
APTを小文字にしただけだと思ったが違い、aptitudeの略らしい。(どうでもいい)

もともと存在していたapt-getの設計上のミスを克服したものである。との公式発表がなされている。
また、upgradeの動作にも違いがあるとのこと。
それは、パッケージの依存関係の変更による現在保有していないパッケージのインストールが必要になった際に現在のパッケージ構成を変えないapt-getではインストールせずにupgradeを停止してしまう事。
aptであれば、更新された依存関係に合わせてインストールしてくれるようです。 今まであったミスも克服したし使ってよねってことらしい。
現状apt-getも使えるようにはなっているが、今後のUbuntu等のディストリビューションのバージョンアップデートの際に非推奨ですって消したりされてもおかしくないかもしれないね。

aptitude


APTの外部プロジェクトとして開発されたものでGUIに対応させたものらしい。
派生した後継という立ち位置らしいが、どうも仕事で指定された18.04では標準インストールされていないものになっている。 もう少し前のバージョンでは標準インストールされていたという話も聞く。
対話型プログラムであり、コンソール準拠のグラフィカルモードを備えているとのこと。
apt-getではできなかったupgradeの際の依存関係変更のパッケージインストールを行う点や、apt-getではパッケージ削除の際に依存関係のために入れたパッケージを消せない(autoremoveオプションをつければ可能)点も改善している。(aptでも消せる)
Debianの公式ではapt-getよりも合理的なパッケージ管理ツールだとのことで今のところはDebianでは残っているらしい。
なんでUbuntuからは消されちゃったんでしょうね?

最後に


あくまで概要をさらっと述べました。
ざっと見た情報等をもとにどれ使うのかってなればaptを使えば問題なさそうだね。
細かいオプションはまぁ、ざっくり見てきた感じあんまり変わらなさそうな印象だけれども、たぶん同じパッケージでも名称が違ったりするんだろうなぁ。そういったところに慣れていかないと始まらないんだろうと感じましたね。

後、調べてて思ったのがaptitudeの情報量少なくないかい?話題に出てくる割に使ってる人ほとんどいないのかな?
それともaptが優秀なものとして出てきて粛清されたのか...
そんなことを考えながら、今回はこの辺で。