文字列をビットローテーションして暗号化するソフトを作りたいのですが上手くいきません。
簡単なやり方があれば教えてください。
ちなみに、数字でのローテーションは出来ました。
文字(char)だと上手くいきません。
////////////////////////////////
// int nKey ずらすビット
// char mask nKeyだけ既にずらしてあるマスク
// char chWord元の文字列
temp = chWord & mask;
chWord = chWord << ((char)sizeof(char)*8 - nKey);
temp = temp >> nKey;
chWord = chWord | temp;
No.4ベストアンサー
- 回答日時:
No.3の補足に対する回答
暗号化したファイル(出力ファイル)には 0x00 ~ 0xff まですべての文字コードが出力されるので、バイナリモードで出力しないとなりません。
また、可読文字以外の文字(例えば改行やタブ)になる可能性もある事に注意。
テキストモードで書き出すと変になると思います。
まずは、バイナリモードでファイルを読み込み、そのまま何もせずバイナリモードでファイルを書き出すプログラムを書いてみましょう。
それを動かして jpeg ファイル等のバイナリファイルを読み込ませて「ファイルがそのままコピー」されればOK。
あとは、読み込みと書き出しの間に暗号化の処理を追加するだけです。
No.3
- 回答日時:
>しかし、スライドするビット数、または文字によりローテーション結果が0になってしまうことがあります。
(もちろん、ビットだけ見るとスライドしています)回答のコードでは、ずらすビット数(nKey)は0~8の範囲である必要があります。
(0と8では何もせず元のデータと同じ物が生成されます。9以上ではビットシフトにより桁溢れが発生しデータが失われます。負の数では結果は未定義です)
ずらすビット数を「直前に暗号化したデータに基づいた可変の値にする」などの処理を行う場合には、nKey を0~8の範囲に制限しなければなりません。
ずらすビット数は0と8では同じ結果になるので、0~7の値を使うのが良いでしょう。
return (char)(((((int)chWord) & 0xff) * 257) >> (nKey & 7));
と修正するのが良いと思います(デコード部分も同じように修正します)
この回答への補足
たびたびありがとうございます。
ただ、文章が稚拙で申し訳なかったのですが、以前の補足をさらに、補足しますと・・・
例えば,「2」という文字を2ビット右にシフトします。
すると、ビット自体は教えて頂いた通りシフトされるのですが、このシフト結果を、いざファイルに書き出そうとしても文字列としては""になってしまい。どうにも出来ませんでした。
こういったことを回避する方法は、あるのでしょうか?
すいませんが、教えてください。
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 でやっておけば良かった気がします(笑)
この回答への補足
ありがとうございます。教えていただいた方法で出来ました。
しかし、スライドするビット数、または文字によりローテーション結果が0になってしまうことがあります。(もちろん、ビットだけ見るとスライドしています)
これは、ビットローテーションを行う上では仕方ないのでしょうか?
それとも、まだ、何かやり方に問題があるということなのでしょうか?
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 倍してからシフトする」部分にあります。
どうして「これでうまく動くのか」は省略しますので、考えてみて下さい。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 int temp = 0; if(isdigit(arr[i])){ temp=arr[i] 2 2022/03/27 01:44
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# int temp = 0; if(isdigit(arr[i])){//文字が数字であれば(0~9) 1 2022/03/27 01:37
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# 【C言語】全角文字の配列を、全角のまま1文字ずつ出力する方法 4 2023/05/09 15:08
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
- PHP c言語 文字 - '1'+26 3 2022/03/26 20:58
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
CStringをwchar_tに変換したい
-
charでの計算?
-
テキストデータをそのままバイ...
-
VC++でコンパイルエラーが出ま...
-
sizeof(char *)
-
main の引数には const 付けた方が
-
atoi( ) の反対をやりたい
-
c言語です。
-
構造体の各メンバにfor文からア...
-
str系関数を使わずに二つの文字...
-
Visual Studio strcpyについて
-
'const char *' 型は 'char *' ...
-
char* を渡したとき、不適切なP...
-
干支のプログラム
-
C言語のfor文です。 繰り返しの...
-
文字列をビットローテーション...
-
ソケット通信で大容量のメール...
-
pingの結果を取得する方法
-
3桁区切(コンマ)記号をつけ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
C言語のfor文です。 繰り返しの...
-
テキストデータをそのままバイ...
-
charでの計算?
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
atoi( ) の反対をやりたい
-
2曲同時再生するにはどうした...
-
C言語の入力した文字を反転させ...
-
配列をnビットシフトする
-
3桁区切(コンマ)記号をつけ...
-
int main()の・・・
-
型変換
-
CStringをwchar_tに変換したい
-
'const char *' 型は 'char *' ...
-
間接操作のレベルとは
-
double型の値をchar配列に変換...
-
c++ 文字列を入力して、一文字...
-
絶対パスからのファイル名の切...
-
switch文で文字を比較すること...
おすすめ情報