こんにちは、インフラちーむのどらくまです。
最近、家で使っている加湿器をやっとしまいました。
まったく気づかず過ごしておりましたが、どうやらこの加湿器、壊れていたようです。
電源を入れると「ウィーン」と音がしますが、よく見てみたら、まったくミストが出ておりません。
これでは「ウィーン」という音が聞きたいときにしか使い道がないので、年末には新しい加湿器を買おうと思います。
前回までのあらすじ
前回のブログにて、ポート番号メーカーのポート番号変換方法を紹介しました。
変換方法をざっくり簡単に言ってしまいますと、言葉をそのまま数字にするのではなく、言葉を分解して、言葉の響きから数字に変換していきます。
分解方法は、ほとんど1文字ずつなのですが、2~3文字をセットにしたほうが語呂合わせしやすい場合、複数の文字で1つの数字に変換することにしました。
ただ問題がありまして、ポート番号は0~65535までしか使えません。
使う人はどんな言葉を入れるのかわかりませんから、6桁以上の数字に変換されることは多々あります。
となると、何かしらのルールに則って、使う文字、使わない文字を決めなければなりません。
では、どのように決めればうまくいくのでしょうか。
今回は65535を超えた数字が出た場合、どのように数字を65535以内にしているのか、これを見ていきたいと思います。
65535を超えた場合
複数文字が出てくるとちょっと厄介ですので、ここでは、新たに一文字で分解できるものを選んでみました。
例)「にんじゃはっとりくん(忍者ハットリくん)」の場合
【にんじゃはっとりくん】
に・ん・じ・ゃ・は・っ・と・り・く・ん
を数字に変換すると、22881069 です。
言葉→変換数字
に →2
ん
じ →2
ゃ →8
は →8
っ
と →10
り →6
く →9
ん
※「ん」と「っ」は言葉の響きがないため、数字に変換しないよう設定してあります。
なんでこの数字になるかは、ポート番号メーカーで該当の文字を入力していただければわかるかと思いますので、ここでの解説は割愛させていただきます。
今回の数字をすべてくっつけると 22881069 になりました。
大幅に65535を超えています。
これをどうするか?
優先して使う文字の選び方
変換した数字を「使う」「使わない」だけを決めてポート番号にしたら、言葉によっては、全部使いたいときや、使える文字が全然ない、という状況もありえます。
ですので、入力された言葉は、できるだけ多く使う、だけれど65535は超えないようにするにはどうすれば良いでしょうか?
色々考えた結果、変換した数字を「使う」or「使わない」、で決めるのではなく、それぞれ優先度を決め、できるだけ優先度の高いものを使う、という方法が理想に近いと感じました。
文字の響きから数字を連想しやすいほど優先的に使うよう設定すれば、そこそこ納得できる結果が出るはずです。
今回の場合であれば、以下の様な感じ。
言葉→優先度
に →1
ん
じ →3
ゃ →3
は →2
っ
と →2
り →7
く →1
ん
※「ん」と「っ」は数字に変換しないため、優先度もありません。
「に」→ 2
「く」→ 9
言葉の響きから数字が連想されやすいものほど、優先度が高くなっており、無理矢理こじつけた感満載なものに関しては、優先度が低くなっています。
どの優先度まで使うのか?
今回のように優先度1の物は何文字、優先度2のものは何文字、とあらかじめ決まっていれば、優先度2までを使おう、ということができるかもしれません。
ですが、実際は誰がどんな言葉を入力するかはわからないため、事前に「ここの優先度まで使う」ということは決められないのです。
では、どのようにポート番号を決めるかというと、まずは、言葉から数字に変換されたポート番号が65536以上かを確認します。
で、65536未満であれば、すべての文字を使い終了なのですが、65536以上の場合、以下のようにして結果に近づけていきます。
- 優先度1の文字のみ抜き出してそれでポート番号に変換
- ポート番号は65536以上か?
- 優先度2の文字のみ抜き出してそれでポート番号に変換
- ポート番号は65536以上か?
- 優先度3の文字のみ抜き出してそれでポート番号に変換
- ポート番号は65536以上か?
・
・
・
と永遠と繰り返していきますと、いつかは65536以上になるときが必ずやってきます。
65536以上になった時点で次の処理に移ります。
65536以上になったら、その時点でポート番号としては破綻しています。
そのため、65536以上になった優先度をまるまる使うことはできませんが、
直前の優先度まではすべて使えるはずです。
では、直前の優先度までで使う、で良いかと思いきや、
直前の優先度までだけだと、かなりもったいないのです。
例えば、優先度が以下の状態だとするとどういうことが起こるか?
2221222
優先度1までしか使えず、ポート番号が1桁になってしまいますよね。
これはまずいです。
できるだけ65536に近づけるには?
なので、低い優先度のものは全部使うことができなかったとしてもできるだけ65536付近で結果を出すようにしてみました。
どのようにしているかと言いますと、
- 今使われている優先度の中で一番低いものを1つ抜いてみる
- ポート番号は65536未満か?
- 今使われている優先度の中で一番低いものをさらにもう1つ抜いてみる
- ポート番号は65536未満か?
- 今使われている優先度の中で一番低いものをさらにもう1つ抜いてみる
- ポート番号は65536未満か?
・
・
・
と繰り返していき、65536未満になった時点で、ポート番号を決定します。
このような処理をすることで、できるだけ多くの文字を使用しているのです。
一番低い優先度は複数あるのですが、何を1つ抜くかと言いますと、一番後ろの文字を抜いています。
これは後ろよりも、前にある文字ほど重要性が高いと考えているためです。
これが入力された文字をポート番号に変換するための概要でした。
見た目は冗談みたいなツールですが、中では曖昧さはなく、どんな言葉が入力されたとしても、一貫性を保って変換しています。
ランダム変換裏話
ポート番号メーカーは、好きな言葉を入れてもらえれば、自動的にポート番号に変換します。
とはいっても、「好きな言葉すぐ思い浮かばないんだよね」という人のためにランダム変換も用意しました。
で、このランダム変換ですが、ランダムで選ばれているように見ますが、ある程度決められたものの中から1つを抽出しているだけです。
スタートし、カウントダウンした後、数字がルーレット形式で回ります。
見た目上は1024~65535すべて出るように数字を回しているため、ボタンを押すたびに何がでるかわからないような感じになっていますが、実際は、決められたものの中から、ランダムで1個抽出し、それを結果として表示しているのです。
なので、11111など言葉に変換しにくいポート番号は絶対出ないようになっています。
そんなわけで、数字をルーレットで回す必要性はまったくないのですが、ルーレットを回したほうが本当にランダムで選んでいる雰囲気が出るのでこのようにしてみました。
良かったらランダム変換でも遊んでみてください。