• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:文字列をビットローテーションしたい)

文字列をビットローテーションして暗号化する方法

このQ&Aのポイント
  • 文字列をビットローテーションして暗号化するソフトの作り方を教えてください。
  • 数字のビットローテーションはできるが、文字(char)では上手くいかない場合の対処法はありますか?
  • ビットローテーションによる文字列の暗号化について詳しく教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.4

No.3の補足に対する回答 暗号化したファイル(出力ファイル)には 0x00 ~ 0xff まですべての文字コードが出力されるので、バイナリモードで出力しないとなりません。 また、可読文字以外の文字(例えば改行やタブ)になる可能性もある事に注意。 テキストモードで書き出すと変になると思います。 まずは、バイナリモードでファイルを読み込み、そのまま何もせずバイナリモードでファイルを書き出すプログラムを書いてみましょう。 それを動かして jpeg ファイル等のバイナリファイルを読み込ませて「ファイルがそのままコピー」されればOK。 あとは、読み込みと書き出しの間に暗号化の処理を追加するだけです。

guuhi
質問者

お礼

ありがとう御座いました。 がんばってみます。

その他の回答 (3)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

>しかし、スライドするビット数、または文字によりローテーション結果が0になってしまうことがあります。(もちろん、ビットだけ見るとスライドしています) 回答のコードでは、ずらすビット数(nKey)は0~8の範囲である必要があります。 (0と8では何もせず元のデータと同じ物が生成されます。9以上ではビットシフトにより桁溢れが発生しデータが失われます。負の数では結果は未定義です) ずらすビット数を「直前に暗号化したデータに基づいた可変の値にする」などの処理を行う場合には、nKey を0~8の範囲に制限しなければなりません。 ずらすビット数は0と8では同じ結果になるので、0~7の値を使うのが良いでしょう。 return (char)(((((int)chWord) & 0xff) * 257) >> (nKey & 7)); と修正するのが良いと思います(デコード部分も同じように修正します)

guuhi
質問者

補足

たびたびありがとうございます。 ただ、文章が稚拙で申し訳なかったのですが、以前の補足をさらに、補足しますと・・・ 例えば,「2」という文字を2ビット右にシフトします。 すると、ビット自体は教えて頂いた通りシフトされるのですが、このシフト結果を、いざファイルに書き出そうとしても文字列としては""になってしまい。どうにも出来ませんでした。 こういったことを回避する方法は、あるのでしょうか? すいませんが、教えてください。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

少し訂正。 int にしてから 257 倍する前に、上位バイトをマスクするのを忘れていました。 char mask(char chWord,int nKey) // int nKey ずらすビット数 // char chWord 元の文字 { return (char)(((((int)chWord) & 0xff) * 257) >> nKey); } char unmask(char chWord,int nKey) // int nKey 戻すビット数 // char chWord 暗号化した文字 { return (char)((((((int)chWord) & 0xff) * 257) << nKey) >> 8); } 最初から unsigned char でやっておけば良かった気がします(笑)

guuhi
質問者

補足

ありがとうございます。教えていただいた方法で出来ました。 しかし、スライドするビット数、または文字によりローテーション結果が0になってしまうことがあります。(もちろん、ビットだけ見るとスライドしています) これは、ビットローテーションを行う上では仕方ないのでしょうか? それとも、まだ、何かやり方に問題があるということなのでしょうか?

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

符号付き char を右シフトすると、処理系(C言語の種類やプラットフォームの種類)によっては、予想外の結果になります。 符号付きを右シフトすると符号が保存される為、思った通りの結果になりません。 例えば、2進数で「11011001」を右に2ビットシフトすると「00110110」にはならず「11110110」になります。 7ビットシフトすると「11111111」になってしまいます。 以下のようにするとうまく行くと思います。 char mask(char chWord,int nKey) // int nKey ずらすビット数 // char chWord 元の文字 { return (char)((((int)chWord) * 257) >> nKey); } char unmask(char chWord,int nKey) // int nKey 戻すビット数 // char chWord 暗号化した文字 { return (char)(((((int)chWord) * 257) << nKey) >> 8); } このソースコードのキモは「int にして 257 倍してからシフトする」部分にあります。 どうして「これでうまく動くのか」は省略しますので、考えてみて下さい。