カテゴリー別アーカイブ: プログラム

この1ヶ月で何個OSを入れたことやら…

ということで愚痴ではないですがメインマシンやらサーバ環境が変わったためにいろんな部分にOSを入れ直していたら…という現象です。特にWindowsでゲームを作っている場合だと引っかかってしまう場合もあるようで、気をつけましょう、というお話。

 

Win10×2、Win8.1×1、Linux(Fedora)×1、…

いろいろなマシンの入れ替えをした結果がこれです。ちなみに今書いているのは私が個人的にインストールを行ったもので、この期間中に別の場所でもOSが動かないやらでヘルプをやっていた関係もあってこれ以上にOSの入れ直しに近いことをやっています。必要な部分では仕方がないのかもしれませんがそれ以外の部分で考えるとなんとも運が悪い状態というべきなのでは…

 

結局この1ヶ月でHDDが(最低でも)2台壊れたことに

1台は前の記事にも書いたとおりサーバ機のHDDで、一応0埋めはできましたし、非常時に一時的な記憶装置として使えそうなので保存しておくとして。問題はなんともう1台壊れた、ということです。2つ目のところは不幸中の幸いにもRAIDで保護をかけている領域だったので一時的に縮退運転に切り替えてまあなんとかしました。なんか転送速度がおかしいなあ~と思ってSMARTを見てみると怪しげなREAD ERRORとWRITE ERRORが記録されていて…。びっくりもいいところ。早めに気がついてよかったです。なんか以前の記事でも書いたような気はしますが、RAID領域でエラーが起こった場合はちゃんとメールを飛ばすようにしておいた方がいいですね。特に今回の問題発覚は定期的に行っているRAIDのチェック作業で引っかかったものですし、メールを飛ばす仕掛け(+受け取る仕掛け)があればチェック後すぐにわかったはずですからね。

 

Win8.1+VisualStudio2015(以降)のランタイムインストールは要注意

というのがこの記事の本題。VisualStudio2015以降のランタイムではUCRT(ユニバーサルCRT)というものができたらしく、それが使われるようになったと。このあたりはこの頃プログラムをいじっていないのと開発環境を更新していないために知らなかったことなのですが、問題はこのUCRTのランタイムを入れるためにはWin10では何も問題はないのですが、Win8.1ではとあるWindowsUpdateを適用しなけれならないという制約があるということです。今回、マシンを入れ替えた関係でWin81も新しくインストールしてアプリテスト用の領域に入れ直そうとしたのですが、これを知らなかったのでUCRTが入らず、プログラムの動作テストをしてみたところ一部の最新のプログラムが動かせない、という状態に陥ってしまいました。

自分の感覚ではOSを入れ終わるとドライバやら必要なランタイムを入れてからWindowsUpdateで最新の状態に持って行くのが正しいと思っていたのですが、今回はそうではなくOSのインストールが終わり、初期ドライバが設定できればWindowsUpdateを強制で何回か行い、WindowsUpdateが何も出ない状態にしてからインストールしたほうがよういのではないか?ということにいつの間にかなってしまったようです。VisualStudio2015のランタイムを入れさせるようなプログラムを作っているそこのあなた。まだすべてのユーザがWin10になったわけではないのでこういう点で動かない、といってくるユーザもいるかもしれませんので気をつけましょう。

 

やっと悪運が切り離せたかな

HDDの故障やらなんやらによる問題もなんとかなった、というところで悪運はすべて切り離せたかな、というところです。あとは自分にくるはずの金運やら仕事運やらを一気につかんでいきたいところだな、というところです。…ですよね?

しばらくWindowModePatchの機能向上に取り組む予定

この手の情報は基本的にTwitterに書くのですが、今回はblog側にも書いておこうかと思います。

 

やはりDirectDraw周りのエミュレーションがあまい

特にDirectDraw+Direct3Dの組み合わせになるとかなり微妙なようです。DirectDrawをそのまま使うタイプの解像度処理だと色深度によって問題が出ることもあるらしく・・・というところで、Direct3D9を使ったエミュレーションだとその辺が完全に実装できていないのでエラーを返される場合も多々あるようです。

 

ということでその辺の処理を追加実装する予定に

一応どう実装するかは決めているので後はコツコツとエミュレーションを書いていくだけです。例えばDirect3DをDirect3D9を使ってエミュレーションするクラスの出だしは

 

class CDirect3DOnDirect3D9 : public CUnknownBase, public CDirectDraw7OnDirect3D9Holder, public IDirect3D, public IDirect3D2, public IDirect3D3{

 

となります。なんじゃ、こりゃ?といいたくなるプログラムコードです。しかし本当にこういうコードを内部的に書いています。特にひどいのがIDirect3DとIDirect3D2とIDirect3D3を同時に実装するというところ。もう少し各クラスに互換性があれば上位だけを実装して強制型キャストですむのですが、この3つにはその手の関係が微妙にないのでこんな実装をするしかないようです。ちなみにIDirect3D7だとIDirect3D3以前とはまた違った実装をしているのでこれは単独で組んでいます。おそらく残りの実装も面倒なのでしょうね。まあ、暇な時間を見つけて作っていきたいと思います。

WindowModePatch 0.68 Alphaを公開

実はこの記事を書く時点で公開してからすでに一週間経過していたりするのですがそれはおいておきましょう。前回の更新から半年前後経過していて忘れ去られていたのかといえばさにあらず。いまだけ時間を作ることができる状態だったことと気になったプログラムが残ったままになっていたので自分でサンプルを作って仮想マシン上で動作をテストすることで修正点を見いだすというマッチポンプではないけれども似ているようなことを二週間前くらいから行って更新にこぎ着けました。

 

主な更新は二つ

基本的には以下になります。

  • DirectDrawをDirect3Dでエミュレーションを行う場合に8bitパレット処理における互換性の向上
  • パッチ対象の拡張子がexe,dll以外である場合に処理が行うことが非常に困難であったので修正

サンプルプログラムを作ってテストしていたのは前者で特に文字列描画で文字色が本来白色にならなければならない場合での互換性が向上しているはずです。検証プログラムを詳細に書いてみて初めてわかる仕様というのもあるのですね…。後者は特に外部モジュールを読み込んで動作するタイプの場合に本体に非推奨の完全パッチ処理を行いライブラリのロード時に強制的にWindowModePatchを読み込ませるか外部モジュールそのものにパッチ処理を行うか…という選択肢で外部モジュールの拡張子がdllではなかった場合にリネームしないとパッチ処理ができないのが面倒ということで処理を変えました。元々パッチ処理では対象が実行ファイル系かどうかの判別が入っているので問題はないのですが、実際にそういうことが必要になるゲームに出会うとさすがに変えたくなるということだったりします。

 

付け加えようとしていた機能はなんだろう?

機能の追加については数ヶ月前に思い立ったことなのでどうしようとしたか今の自分には理解できない…じゃなくて。おそらく途中で解像度を切り替える機能とかのはずなのですが機能が中途半端に実装されているので今回の更新では対象としていません。というか数ヶ月前の私は最終的にどの形にして実装をするつもりだったのか、について今の私にはわからない、という状態だったり。おそらくは対象のゲームと関係のないキーの組み合わせを入れると別のダイアログが表示されて画面の解像度をリストから選ぶか入力するか、という感じだと思うのですが…。まあ、余裕があれば適当に実装してみたいと考えてはいます。

 

自分一人での更新も難しくなってくるのかな

フリープログラマというのも自分で宣伝できなかったり仕事を受ける人脈がない場合はフリーターより悪い状況と見えるので真面目に職に就こうかと思い活動しています。そうするとこのWindowModePatchのメンテナンスも全くできなくなる、ということになる予感がしておりもったいないような気がしているのでいろいろと方策を考えています。信頼できるほかの人にソースコードを更新できる権限を持ってもらって対応できるゲームを増やしていったり情報を集めたり、などですね。

なお、WindowModePatchに関するWikiもこのサーバー内に設置してあり、容量制限もつけたのでデザインが整ったら…と思っていたのですが使っているWiki(MediaWiki)が昔に記事を書いたときから見るとかなり更新されてしまったためにどうしても情報を書くときに使おうと思っているWikipediaのテンプレートであるInfoboxが正常に取り込めないという問題にはまっていて抜け出せないのですね。はてさてどうするのがよいのでしょうか…。

 

Hash Calculator 0.02を公開

というわけでハッシュ計算につきまして新規にいくつかのアルゴリズムを実装すると同時にバグ修正を行いましてHashCalculatorを更新しました。なんと初期公開が2012年末ということで4年以上間隔が空いているのがびっくりというところです。

 

計算可能なハッシュアルゴリズムの追加および更新をしてみた

一つ前の記事で自分のライブラリに追加する、という話は書いていたと思いますがアルゴリズムを追加するということはHashCalculatorも更新できるネタができた、ということだったのでマイナーなアルゴリズムだけではなくもう少しメジャーなアルゴリズムも追加してみました。今回追加したのは

  • BLAKE(224bit,256bit,384bit,512bit)
  • BLAKE2b,BLAKE2s
  • SM3

の3種類になります。BLAKEはSHA-3の公募が行われたときに最終候補にまで残ったアルゴリズムとして有名でBLAKE2系はそれの改良系であり、MD5並みの計算速度を持つということを売りにしているアルゴリズムです。SM3は中国で標準のハッシュ処理として計算方法が公開されているもので中国圏で開発されている規格などでハッシュ処理を使うときによく使われている形式となっています。BLAKEについては公募の関係でドキュメントなどもかなり豊富にあるのですがSM3は範囲がかなり狭く国が公開している中国語の物かIETFが公開しているドキュメントくらいしかないようでIETFのものがあるとは知らず実装テストが終わるまでずっと中国語のドキュメントを訳してやっていました。まあ、数式の部分は共通ですし訳す必要がある部分も中国語の文法などを簡単に知っていれば漢字の意味をある程度共通にとれるので難しくはないところがありがたかったです。

 

KeccakとSHA-3の計算方法は「終端が微妙に」違う

「皆さんも気をつけましょう」という話題です。SHA-3のアルゴリズムは本家であるKeccakをそのまま使っていますが最後のメッセージパディングの部分が微妙に違います。これはSHA-3の仕様をちゃんと確認してみるとよいですがKeccak本体だとメッセージパディングは数式を使わず言葉で書くと

1を追加して0を(ブロック長ビット数-1)まで追加後最後に1を追加する

ですが、SHA-3だとSHA3-nとSHAKEnでは

SHA3-n:01を追加してkeccakの終端処理(1を追加して…)を行う

SHAKE-n:1111を追加してkeccakの終端処理(1を追加して…)を行う

となります。このあたりは仕様書をちゃんと読んでおく必要があると思いますので気をつけてください。多分以前に作ったサンプルだとKeccakの終端処理を使っているために間違っているような気がしないでもないです。

 

中国の暗号化規格であるSMnって複数あるのですね…

SM2とかSM3とかSM4とかあるようです。多分日本語のサイトで言葉を検索すると全く違う単語に引っかかるでしょうね。私も時々「三國無双」の略称じゃないの?と考えしまうこともあるくらいですから。ちなみにそれぞれ

  • SM2:楕円曲線を使った公開鍵暗号方式
  • SM3:SHA-256相当のハッシュ関数
  • SM4:ブロック構造を使った共通鍵暗号方式

となっています。最新の規格もあるようですが今回はそこまでは見ていません。「中国製のCPUで処理に対応した、という記事を見て実装してみたいと思った」というなんとも微妙な動機でやり始めた今回の拡張ですがこの数年間で暗号にまつわることも大分発展したのだな、と思いました。なお私個人だと暗号に用いられる数学の根本的な部分を学びましたので楕円曲線でなぜRSA暗号が成立するのか?といった部分もいまなら説明できるようになっています。

 

ついでにコンパイラのバージョンもアップ

VisualStudio2005からVisualStudio2010に変更しまして対応OSもWin8系およびWin10系を追加しました。これが今回の副産物ですね。数年前にVisualStudio2005で作成して公開したきり一度も更新していないプログラムが複数ありますがそれもやった方がよいのかな…と思っているところです。

SM4(formerly SMS4)を実装してみた

久しぶりのプログラムネタです。題名を見ても「は?」としか思われないかもしれませんね。

 

SM4(formerly SMS4)とは

おそらくこれの意味がわからないと思いますので説明を。SM4を単体で検索してもまともに出てこないですしSMS4で検索すると今回のものとは全く無関係のことが出てくるほどマイナーなアルゴリズムですので。

このアルゴリズムですが実はブロック暗号アルゴリズムの一つで中国ではよく使われている形式です。中国国内で使われる無線通信の暗号形式として登場することが多いようで、これを実装してみようと思った理由がVIAもといCentaurの流れを汲む8コアx86 CPUが中国で登場していた模様 – やじうまPC Watchの記事を読んでいるときにSMS4が追加サポートされたという部分があり、「どういうアルゴリズムなのだろうか?」というところからどうせなのでプログラムとして実装してみよう、という流れでやってみました。

なお、ドキュメントなどを探せばわかると思いますが本来のアルゴリズムを説明した文章は中国語(汉语)で書かれていてそれを英語に翻訳したものが別に存在しています。ほとんどの人は英語版を読めばよいと思いますが中国語(汉语)が読めるのであればそちらのバージョンを読んでみてもよいと思います。汉语を少しですが勉強していたので読んでみたのですが、読み方はわからない漢字が大量にあっても文法がある程度理解できるようになったので意味を大筋で理解できるのが面白かったですね。

 

アルゴリズムはXOR、SBox置換、巡回シフトを1ラウンドとした複数ラウンド構成

暗号キーの作成も暗号化の手順もほぼ同じ手順(線形処理である巡回シフトの式が異なるだけ)で、かつ処理の構成の方法から暗号キーから内部暗号キーを作り出してしまえば暗号と復号は内部暗号キーを使う順番が逆になるだけ、という至ってシンプルなアルゴリズムです。何回か暗号処理を実装した人であれば最適化を考えなければ数時間で完了できるほどのものです。

一部面倒なのはこの手のアルゴリズムの実装では当たり前の話なのですがエンディアン処理をうまくすることです。巡回シフト演算の関係で32bitワードの状態での演算が必要でその部分がビックエンディアンで行う、という定義なのでリトルエンディアンを前提としたコードだとどの部分に変換処理を入れる必要があるのか、を正しくすることが重要になってきます。この部分に気がつくのに時間がかかったために資料に記述されている例と状態が合わないために四苦八苦しました…。

 

実装しても使い道が…

まあ、中国語(汉语)のドキュメントを直接読む機会となりよい経験ができた、というところでしょうかね。もちろん普通のブロック暗号なのでCBCなどと組み合わせれば普通にファイルの暗号化もできるのですが、だからといってゲームのアーカイブなどに使ってみても意味がなさそうですし。それ以外だと一からプログラムを組む機会が少なくなっていたのでそちらでもよい刺激になった、というところで。

もしコードを見てみたい、という人がいればコメントにでも書いてもらえれば追加で記事にするかもしれません。