文字列のバイナリ化 – プログラミング – Home

通知
すべてクリア

[解決済] 文字列のバイナリ化

固定ページ 1 / 2

GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

いつもお世話になっています。GGです。

データをfwrite(...)で保存しています。
データの一部は文字列があります。
例:
123,3334,QQQ,RRRR,4444
...
というデータです。

保存結果は文字部分がバイナリ化していない。
(テキストファイルとして開くと文字列がそのままで表示されています)

文字列のバイナリ化したいのですが、
いい方法があるのでしょうか。
(ファイルの暗号化以外の方法)

よろしくお願いします。

環境:.Net(2002) MFC使用、Win2000


引用未解決
トピックタグ
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

テキストファイルってのは「可視な文字だけでなるバイナリファイル」なんだから
(可視)文字コードをそのまま fwrite したらエディタで見えるのは当然の話。

暗号化で無くバイナリ化とは何を意図しているのか?
本当にしたいのは暗号化なのでは?


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

tetrapodさん、
ご返事ありがとう.

>テキストファイルってのは「可視な文字だけでなるバイナリファイル」なんだから
>(可視)文字コードをそのまま fwrite したらエディタで見えるのは当然の話。

そうですか、わかりました。

>暗号化で無くバイナリ化とは何を意図しているのか?
自分で決まったフォマットを公開したくないことです。

>本当にしたいのは暗号化なのでは?
本当にはファイルを暗号化にしたいのですが、時間がなくて、
(暗号化について知識がないため)
一応簡単にバイナリして、(フォマットを公開したくないことです)
データを他人に渡すこと。

そういう目的のですが、何か簡単な方法があれば教えてください。

よろしくお願いします。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

ぱっと見なにがなんだかわかんなくするだけなら、
たとえば各ビットの1/0をひっくり返して書き/読みます。


返信引用
momo
 momo
(@momo)
ゲスト
結合: 23年前
投稿: 12
 

>本当にはファイルを暗号化にしたいのですが、時間がなくて

BlowFishを使えば簡単に暗号化できますよ。
検索すれば、簡単に解説サイトに辿り着けます。


返信引用
オレンジフィッシュ
 オレンジフィッシュ
(@オレンジフィッシュ)
ゲスト
結合: 18年前
投稿: 58
 

擬似乱数を使って XOR をとるのはどう?

char str[] = 123,3334,QQQ,RRRR,4444;
int i, len = strlen(str);

// 乱数で暗号化
RandInit( 初期値 );
for ( i = 0 ; i < len ; i++ ){
 str[ i ] = (char)(str[i] ^ Rand());
}
fwrite( str, len, 1, fp );

Rnad() は自作の擬似乱数で適当な数式より 0~255 が発生するようにしておく。
復元は同じ Rand() を使って暗号化と同じ処理を文字列の長さ分だけ行えばよい。
なお Rand() の乱数が暗号化したときと同じ数から乱数を発生できるように
RandInit() も用意して初期値を設定できるようにしておくこと。
そうしないと正常に復元できない。

// 同じ乱数で復元
char buff[文字列長 + 1];

fread( buff, 文字列長, 1, fp );
RandInit( 初期値 );
for ( i = 0 ; i < 文字列長 ; i++ ){
 buff[ i ] = (char)(buff[i] ^ Rand());
}
buff[i] = '\0';
printf( 復元:[%s]\n, buff );


返信引用
yoh2
 yoh2
(@yoh2)
ゲスト
結合: 18年前
投稿: 70
 

望みの暗号化のレベルは以下のどちらでしょうか?

1. ぱっと見、分かりにくくしたいが、解読されてしまっても別に構わない。(スタンドアローンゲームの
セーブデータとか)
2. 解読されることは可能な限り避けたい。

1なら既出のビット反転等の方法で十分事足りると思います。

2の場合は難しいですね。そういった必要性に迫られたこともないため、よい方法を思い付きません。
既出の例だとBlowfish、他の有名所ではAESや3DESのような本格的な暗号化アルゴリズムを利用すること
になると思いますが、秘密鍵の管理が難しいです。
下手にプログラム中でハードコーディングでもしようものなら、並レベルのクラッカーにあっさり解析され
て1と同じレベルに堕ちてしまいますので。


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

επιστημηさん、momoさん、オレンジフィッシュさん、yoh2さん
コメントありがとう。

(επιστημηさんから)
>たとえば各ビットの1/0をひっくり返して書き/読みます。

(オレンジフィッシュさんから)提示した例と同じことですね。

(momoさんから)
>BlowFishを使えば簡単に暗号化できますよ。
>検索すれば、簡単に解説サイトに辿り着けます

ざっと見ました、時間があったら、やろうと思っています。
(BlowFishということが知らなかった。情報ありがとう。)

(オレンジフィッシュさんから)
提示した例、ほんとにありがとうございました。

その例を見ながら、やってみました。
問題がなくうまくできました。

でも、構造体の場合もやってみました。
一つの問題があります。
例:
struct DFMData {
int DfmLaye; // 文字のLaye
int DfmBcode; // 文字のBcode
int DfmType; // 文字のType
char DfmName[STR_NAME2]; // 文字のName
int DfmSize; // 文字のSize
int DfmWide; // 文字のWide
long DfmColor; // 文字のColor
int DfmArrange; // 文字の配置
int TextDfmDraw_flag; // 文字の表示非表示
};
   DFMData DFMData_Savedata;


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

επιστημηさん、momoさん、オレンジフィッシュさん、yoh2さん
コメントありがとう。

(επιστημηさんから)
>たとえば各ビットの1/0をひっくり返して書き/読みます。

(オレンジフィッシュさんから)提示した例と同じことですね。

(momoさんから)
>BlowFishを使えば簡単に暗号化できますよ。
>検索すれば、簡単に解説サイトに辿り着けます

ざっと見ました、時間があったら、やろうと思っています。
(BlowFishということが知らなかった。情報ありがとう。)

(オレンジフィッシュさんから)
提示した例、ほんとにありがとうございました。

その例を見ながら、やってみました。
問題がなくうまくできました。

でも、構造体の場合もやってみました。
一つの問題があります。
例:
struct DFMData {
int DfmLaye; // 文字のLaye
int DfmBcode; // 文字のBcode
int DfmType; // 文字のType
char DfmName[STR_NAME2]; // 文字のName
int DfmSize; // 文字のSize
int DfmWide; // 文字のWide
long DfmColor; // 文字のColor
int DfmArrange; // 文字の配置
int TextDfmDraw_flag; // 文字の表示非表示
};
   DFMData DFMData_Savedata;


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

επιστημηさん、momoさん、オレンジフィッシュさん、yoh2さん
コメントありがとう。

(επιστημηさんから)
>たとえば各ビットの1/0をひっくり返して書き/読みます。

(オレンジフィッシュさんから)提示した例と同じことですね。

(momoさんから)
>BlowFishを使えば簡単に暗号化できますよ。
>検索すれば、簡単に解説サイトに辿り着けます

ざっと見ました、時間があったら、やろうと思っています。
(BlowFishということが知らなかった。情報ありがとう。)

(オレンジフィッシュさんから)
提示した例、ほんとにありがとうございました。

その例を見ながら、やってみました。
問題がなくうまくできました。

でも、構造体の場合もやってみました。
一つの問題があります。
例:

#define STR_NAME2 65 //Name

struct DFMData {
int DfmLaye; // 文字のLaye
int DfmBcode; // 文字のBcode
int DfmType; // 文字のType
char DfmName[STR_NAME2]; // 文字のName
int DfmSize; // 文字のSize
int DfmWide; // 文字のWide
long DfmColor; // 文字のColor
int DfmArrange; // 文字の配置
int TextDfmDraw_flag; // 文字の表示非表示
};
DFMData DFMData_Savedata;

for(int j=0; j<30; j++){
 DFMData_Savedata.DfmLaye = mp_TextDfmSct[j].DfmLaye;
 FMData_Savedata.DfmBcode = mp_TextDfmSct[j].DfmBcode;

 strcpy(DFMData_Savedata.DfmName, mp_TextDfmSct[j].DfmName); //名称

 DFMData_Savedata.DfmSize = mp_TextDfmSct[j].DfmSize;
 DFMData_Savedata.DfmWide = mp_TextDfmSct[j].DfmWide;

  //mp_TextDfmSct[j].DfmLayeは配列です

//問題ここから
 int len = strlen(DFMData_Savedata.DfmName);
for (int ik=0; ik<len; ik++){
  DFMData_Savedata.DfmName[ik] =
         (char)(DFMData_Savedata.DfmName[ik] ^ randValue[ra_i]);
  ra_i++;
 }
fwrite(&DFMData_Savedata, sizeof(DFMData_Savedata), 1, fp9);

...

問題:
以上のコードですが、一回目(全体)を実行すると、ちゃんと正しく変換できました。
2回目以降、一部変換ができませんでした。
変換できない部分を見つかりました。

  DFMData_Savedata.DfmName[ik] =
         (char)(DFMData_Savedata.DfmName[ik] ^ randValue[ra_i]);
の前後の文字列が調べた、
変換前 文字列の長さ=22です。
変換後 文字列の長さ=13です。

文字列が変わったということです。
(randValue[ra_i]);は暗号と複号するとき同じ数値を使っています。)
mp_TextDfmSct[j].DfmNameは可変長文字列です。

一体問題はどこでしょう。

説明を理解できるのでしょうか。

よろしくお願いします。


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

追記

>  DFMData_Savedata.DfmName[ik] =
         (char)(DFMData_Savedata.DfmName[ik] ^ randValue[ra_i]);
>の前後の文字列が調べた、
>変換前 文字列の長さ=22です。
>変換後 文字列の長さ=13です。
 int len = strlen(DFMData_Savedata.DfmName);
for (int ik=0; ik<len; ik++){
  DFMData_Savedata.DfmName[ik] =
         (char)(DFMData_Savedata.DfmName[ik] ^ randValue[ra_i]);
  ra_i++;
 }
 int len2 = strlen(DFMData_Savedata.DfmName);

len =22
len2 =13
len とlen2は一致していないです。

よろしくお願いします。


返信引用
yoh2
 yoh2
(@yoh2)
ゲスト
結合: 18年前
投稿: 70
 

暗号化部分だけでなく、復号部分のコードも見ないと確実なことが言えません。

以下推測。
暗号化部分のrandValueと復号部分のrandValue(相当の物)が異なっていたりしませんか?
暗号化部分では、ra_iの値は増えっぱなしですが、復号部分では構造体ひとつの復号が完了する度に0にリ
セットしているとか。

>  int len = strlen(DFMData_Savedata.DfmName);
> for (int ik=0; ik<len; ik++){
>  DFMData_Savedata.DfmName[ik] =
>          (char)(DFMData_Savedata.DfmName[ik] ^ randValue[ra_i]);
>  ra_i++;
>  }
>  int len2 = strlen(DFMData_Savedata.DfmName);
>
> len =22
> len2 =13
> len とlen2は一致していないです。

これは当たり前。'\0'が暗号化によって'\0'でなくなっていますから。
下手すりゃlen2の算出時にプログラムが落ちます。

# ところで、文字列部分しか暗号化していないようですが、その程度のものでよいのですか?


返信引用
yoh2
 yoh2
(@yoh2)
ゲスト
結合: 18年前
投稿: 70
 

またやっちゃった。いい加減学習せねば……

前回の投稿で、&#92; は '¥'または'\'と読み替えて下さい。


返信引用
yoh2
 yoh2
(@yoh2)
ゲスト
結合: 18年前
投稿: 70
 

ひとつ補足。

前投稿の最後の部分の説明は、len > len2となってしまう場合の説明になっていました。
GGさんの、len < len2となっているパターンは、途中(GGさんの例では14文字目)で
変換前のDFMData_Savedata.DfName[ik] == randValue[ra_i]がとなっていて、変換後にゼロにな
るからでしょう。


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

yoh2さん、
ご返事ありがとう。

>これは当たり前。'\0'が暗号化によって'¥\;0'でなくなっていますから。
>下手すりゃlen2の算出時にプログラムが落ちます。

暗号前のLenと暗号後のLen2は
1.Len=Len2
2.Len>Len2
3.Len<Len2
という三つの結果ですか、
1.Len=Len2は、最初一回目の結果です。
2.Len>Len2は、2回目以後の結果です。

必ずLen=Len2と思っていますが、これが間違っていますか?
もし間違っているなら、理由を教えてください。
('\0'が暗号化によって'¥\;0'という理由ですか、
でも、私の場合、エラーの部分ですが、22個文字列ですが、13個目以前は
正常ですが、13目以後、変換していないようです。)

>暗号化部分のrandValueと復号部分のrandValue(相当の物)が異なっていたりしません
>か?
>暗号化部分では、ra_iの値は増えっぱなしですが、復号部分では構造体ひとつの復号が
>完了する度に0にリ
>セットしているとか。

一回目の暗号化部分と復号部分は正常に変換できました。
2回目は同じ関数でもう一度実行するということです。

># ところで、文字列部分しか暗号化していないようですが、その程度のものでよいので
>すか?
いいえ、一行の場合(構造体)どうやるのでしょうか。

よろしくお願いします。

よろしくお願いします。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました