プロが教えるわが家の防犯対策術!

文字列をビットローテーションして暗号化するソフトを作りたいのですが上手くいきません。
簡単なやり方があれば教えてください。

ちなみに、数字でのローテーションは出来ました。
文字(char)だと上手くいきません。

////////////////////////////////
// int nKey ずらすビット
// char mask nKeyだけ既にずらしてあるマスク
// char chWord元の文字列

temp = chWord & mask;

chWord = chWord << ((char)sizeof(char)*8 - nKey);

temp = temp >> nKey;

chWord = chWord | temp;

A 回答 (4件)

No.3の補足に対する回答



暗号化したファイル(出力ファイル)には 0x00 ~ 0xff まですべての文字コードが出力されるので、バイナリモードで出力しないとなりません。
また、可読文字以外の文字(例えば改行やタブ)になる可能性もある事に注意。
テキストモードで書き出すと変になると思います。

まずは、バイナリモードでファイルを読み込み、そのまま何もせずバイナリモードでファイルを書き出すプログラムを書いてみましょう。
それを動かして jpeg ファイル等のバイナリファイルを読み込ませて「ファイルがそのままコピー」されればOK。

あとは、読み込みと書き出しの間に暗号化の処理を追加するだけです。
    • good
    • 0
この回答へのお礼

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

お礼日時:2003/10/03 22:01

>しかし、スライドするビット数、または文字によりローテーション結果が0になってしまうことがあります。

(もちろん、ビットだけ見るとスライドしています)

回答のコードでは、ずらすビット数(nKey)は0~8の範囲である必要があります。
(0と8では何もせず元のデータと同じ物が生成されます。9以上ではビットシフトにより桁溢れが発生しデータが失われます。負の数では結果は未定義です)

ずらすビット数を「直前に暗号化したデータに基づいた可変の値にする」などの処理を行う場合には、nKey を0~8の範囲に制限しなければなりません。

ずらすビット数は0と8では同じ結果になるので、0~7の値を使うのが良いでしょう。
return (char)(((((int)chWord) & 0xff) * 257) >> (nKey & 7));
と修正するのが良いと思います(デコード部分も同じように修正します)

この回答への補足

たびたびありがとうございます。
ただ、文章が稚拙で申し訳なかったのですが、以前の補足をさらに、補足しますと・・・

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

すいませんが、教えてください。

補足日時:2003/10/03 18:02
    • good
    • 0

少し訂正。



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 でやっておけば良かった気がします(笑)

この回答への補足

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

これは、ビットローテーションを行う上では仕方ないのでしょうか?
それとも、まだ、何かやり方に問題があるということなのでしょうか?

補足日時:2003/10/03 16:07
    • good
    • 0

符号付き 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 倍してからシフトする」部分にあります。

どうして「これでうまく動くのか」は省略しますので、考えてみて下さい。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!