• ベストアンサー

簡単な暗号化って出来ますか?

ゲームを現在作っているのですが、セーブデータはどのように作ったらいいのでしょうか? 現在セーブデータは例えば「3面までクリアした」というデータは「3*x」をする事で暗号化(といえる物ではないですが)表し、複合化はxを割ることで求めています。 xの数は十分大きくしておいて、データが改竄されてxの倍数でなければエラーになるようになっています。 こんなんじゃすぐわかってしまうでしょうし、もうちょっとクオリティを上げたいのですが、 セーブデータってどうやってファイルにデータ書き出せばいいのでしょうか? 専門性の高いアルゴリズムや難しいアルゴリズムは必要なく、遊び程度のアルゴリズムでいいので(むしろ簡単な方がいいので)教えていただけないでしょうか。 自分の記録したいデータは全てint型の 「n面までクリアした。」 「現在の最高得点」 「合計プレイ時間」 「x匹敵を倒した」 などのデータです。 よろしくお願いします!

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

  • ベストアンサー
  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

同じ値で2回XORすると元に戻るのを利用して こんなのは int main(void) { int key = 0x45af6e5d; //任意の暗号化キー int num = 5; int crypt; printf("初期値=%d\n", num); crypt = num^key; printf("暗号化=%d\n", crypt); crypt = crypt^key; printf("複合化=%d\n", crypt); return 0; } どうでしょう

Directxq
質問者

お礼

おぉ、まさに私が一番望んでいた答えでした。 単純かつパッとみわかりにくい非常によい方法ですね。 ありがとうございました。

その他の回答 (3)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

以下のような暗号はどうでしょうか。 int型の数値xが保存したい値とすると、この値をint型の定数Aで、AND(&)した値x1とOR(|)した値x2を、求め、この2つの値を保存します。 復元は、x1とx2と定数Aがあれば可能です。 またこのことにより、データのかいざんのチェックも可能です。 以下例を示します。 話を簡単にする為に、定数Aを0xFFFF0000とします。 定数AでANDした値x1は、必ず、下位16ビットが0でなければなりません。(定数Aのビットが0に対応する部分) 定数AでORした値x2は、必ず、上位16ビットが1でなければなりません。(定数Aのビットが1に対応する部分) 上記の条件が全て成立しないとき、データがかいざんされています。 次に復元方法ですが、x1の0x????0000とx2の0xFFFF????の部分の?のビットのみをお互いに合わせれば良いことになります。 x1とx2を合わせるとき、x2は0x0000????の状態に一度変換して(0x0000FFFFでANDをとって)、x1とx2のORをとります。これが求めるxになります。 定数Aは、実際には0xFFFF0000でなく、0xABCD789Eなどのビットの0,1が入り乱れた値がものが良いでしょう。

Directxq
質問者

お礼

なるほど、改竄のチェックも出来るわけですね。 大変参考になります。 是非使用させていただきます。ありがとうございました。

  • usokoku
  • ベストアンサー率29% (744/2561)
回答No.3

私の場合はゲームソフトではありません。 以下の方法で暗号化しています。 1.通常の方法でSAVE 2.ish圧縮をかけて7bitテキスト化(BASE64を使うこともあります) 3.lzh圧縮をかけて8ピット化 4.8bitの乱数表Aで、256バイト単位で順番の入れ替え 5.8bitの乱数表Bで、可逆変換 ここで、乱数表A, Bを作成するルーチンで初期値を起動した時刻にすると、起動するきかいごとに乱数表が変わるので、解読はかなり苦労するはずです。 8ビットですから、256個の配列に順番に数字を入れて、適当な回数、2つ選んだ数値を入れ替えて作ります。 私の場合、取り扱うデータが3-10MBのテキストなので、8ビット内での数値の出現頻度をほぼ均一にするために、ish, lzhを使っています。 これで混ぜてしまうと、特定の場所だけの変更が変な場所まで影響してくれるので所在を特定しにくいです。 データが少ない場合には、適当なゴミを10-20KBつくって、この中に埋め込みます。 どこに埋め込むかは、起動時刻にあわせた乱数で。

Directxq
質問者

お礼

なるほど、ありがとうございます。 クオリティの高いソフトを作る時は是非活用させていただきます。 ありがとうございました。

  • softimage
  • ベストアンサー率61% (68/111)
回答No.1

以下などはどうでしょうか? ・全て文字列としてそれぞれの桁毎に足し算をする。  各桁の数値はプログラム側で保存しておいてください。 ・関係ない数値を作成しておき、ランダムに数値を入れる。 ・上記を一定のルールで並べ替える また、各データの正当性判断いはハッシュ値やCD (重み付きで足し算や掛け算等した下1桁)を 用いるとよいと思います。

Directxq
質問者

お礼

ありがとうございます。 色んなやり方があるなと関心しているところです。 お世話になりました。

関連するQ&A

  • ファイルを暗号化したい

    こんにちは。 外出先でPDAで業務データを入力し、このデータをテキスト化(CSVファイル)します。 テキスト化したファイルをFOMAで会社のFTPサーバーに飛ばそうと 思っているのですが、送るファイルがテキストファイルなので セキュリティの面で心配です。 そこで、PDAで作成したファイルを暗号化し、会社のFTPサーバーでは 複合化してからDBに登録しようと考えているのですが、そのような 事は可能でしょうか? できれば、アプリの中からAPIを呼び出す形で暗号化・複合化したいのですが。 そのようなことができる暗号化ソフトをご存知でしたらご教示ください。 宜しくお願いいたします。

  • 写真を暗号化して配布したいのですが・・・

    独自の暗号アルゴリズムで画像を保護し、閲覧のみ可能なViewerはないでしょうか? サークルで写真を配布することになりました。 ボランティア活動中の写真なのでプライバシーの問題から外に流出することは困ります。 私が考えたのは 1.CPRM対応のDVD-Rでディスクのコピーを禁止 2.写真データを暗号化 での二つで保護することです。 しかし、通常の複合化ソフトではデータ自体をコピーできてしてしまうため あまり安全な方法ではないと思います。 そこで質問ですが、独自の暗号アルゴリズムで画像を保護し かつ閲覧のみ可能なViewerはないでしょうか? できればCPRMによる保護、スクリーンショット禁止などの機能があればうれしいです。 できれば、フリーソフトか、配布側だけに課金されるもが良いです。 サークルのモラルの問題だとは思うのですが、施設側から対応を求められています。 ご教授よろしくお願いいたします。 使用できるソフト Microsoft Office Adobe Creative Suite 3

  • Java(AES)多重の暗号化・復号化、安全?

    メンタル・ポーカー・アルゴリズム↓をJavaで実装したくて http://en.wikipedia.org/wiki/Mental_poker まず、暗号化について調べました。 AESという暗号化の方法を使ってみたのですが、 これなら、多重に暗号化したとして、順番に関わらず、 復号化できるようなので、メンタル・ポーカー・アルゴリズムが実装できると思いました。 しかしながら、私はこのAESという暗号化の方法について、詳しく知りません。 この暗号化方法は、安全なのでしょうか。たとえば、カギがなくとも、暗号前のデータの見当がつく かのようなことが、スーパーコンピュータの手にかかれば一時間もあれば分かってしまう、 というようなことはないでしょうか。 下記は、ランダムな順番で暗号化・復号化してみたコードです↓ 参考になればと思い乗せてみます static void shuffle(int[] array) { for (int i = 1; i < array.length; i++) { int n = random.nextInt(i + 1); int t = array[i]; array[i] = array[n]; array[n] = t; } } public void testAES() throws Exception { String alg = "AES"; byte[] orgData = "abcdefghhijklmno".getBytes(); KeyGenerator keygen = KeyGenerator.getInstance(alg); int keyCount = 16; Key[] keys = new Key[keyCount]; int[] encryptOrder = new int[keyCount]; int[] decryptOrder = new int[keyCount]; for (int i = 0; i < keyCount; i++) { keys[i] = keygen.generateKey(); encryptOrder[i] = i; decryptOrder[i] = i; } shuffle(encryptOrder); shuffle(decryptOrder); byte[][] ivs = new byte[keyCount][]; Cipher cipher = Cipher.getInstance(alg + "/OFB/NoPadding"); byte[] data = orgData.clone(); for (int i = 0; i < keyCount; i++) { int idx = encryptOrder[i]; cipher.init(Cipher.ENCRYPT_MODE, keys[idx]); ivs[idx] = cipher.getIV(); data = cipher.doFinal(data.clone()); } for (int i = 0; i < keyCount; i++) { int idx = decryptOrder[i]; cipher.init(Cipher.DECRYPT_MODE, keys[idx], new IvParameterSpec(ivs[idx])); data = cipher.doFinal(data); } assertTrue(new String(data), Arrays.equals(orgData, data)); }

    • ベストアンサー
    • Java
  • 暗号利用モードの実装

    C言語でAESのEBCモードを実装しようとしています。 unsigned char key[32]; int w[60]; int data[NB]; int nk; int nr; int data2[32]; int Cipher(int *); int invCipher(int *); void encryptEBC(int *,int n); void decryptEBC(int *,int n); main(){ unsigned char keys[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; unsigned char iv[]={0xcb,0x70,0x05,0x9e,0x27,0x2f,0x4e,0xd2, 0xd0,0xbe,0x0b,0x06,0xbf,0x16,0xec,0x5a}; unsigned char init2[]={'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0',0x0a}; int isize = sizeof(init2)/sizeof(init2[0]); int dsize2 = sizeof(data2)/sizeof(data2[0]); printf("%d,%d\n",isize,dsize2); FILE *fp; char *fname = "test.txt"; unsigned char init[16]; int i = 0; int c; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } while( (c = fgetc( fp )) != EOF ){ init[i] = c; i = i+1; } fclose( fp ); memcpy(key,keys,16); nk = 4; nr = nk + 6; KeyExpansion(key); memcpy(data,init,16); memcpy(data2,init2,isize); datadump("PLAINTEXT: ",data,16); datadump("KEY: ",key,16); Cipher(data); datadump("Cipher: ",data,16); invCipher(data); datadump("invCipher: ",data,16); printf("\n"); datadump("PLAINTEXT: ",data2,dsize2); encryptEBC(data2,dsize2); datadump("EBCCipher: ",data2,dsize2); decryptEBC(data2,dsize2); datadump("invCipher: ",data2,dsize2); printf("\n"); return 0; } void encryptEBC(int data[],int dsize){ int tmp[16]; int i,j,k; printf("aiu%d\n",dsize); KeyExpansion(key); for (i = 0; i < dsize; i += 16) { memcpy(tmp,&data[i],16); Cipher(tmp); memcpy(&data[i],tmp,16); } } void decryptEBC(int data[],int dsize){ int tmp[16]; int i,j,k; printf("eo%d\n",dsize); KeyExpansion(key); for (i = 0; i < dsize; i += 16) { memcpy(tmp,&data[i],16); invCipher(tmp); memcpy(&data[i],tmp,16); } } このようなプログラムでとりあえず2ブロック分の暗号化、復号を行おうと思っているのですが、1ブロック目しか行えません。 どなたかどこが悪いのかご教授いただけないでしょうか?

  • PHPの可逆暗号化関数について

    こんにちは、現在PHP ver5とpostgreSQLでデータベースと連携させて使っているのですが、 テーブル内にデータを入れる際、今は平文のまま登録していますが、 この文字列を、暗号化してデータベースに登録し、取り出したい時に複合化して平文に戻せる関数はどういったものがあるでしょうか。 IDやパスワードといった文字列ではないので不可逆暗号化関数では元のデータベースの平文が分からなくなってしまうと思うのですが、 これを暗号化して登録しておき、抽出する際に元に戻す作業をしたいのです。 これってURLエンコード・デコードとは違いますよね・・・。 長くなりましてすみません。わかる方よろしくお願いします。

    • ベストアンサー
    • PHP
  • 暗号化ソフトについて

    現在Win XP Proを使用しています。会社で使っています。今セキュリティ面を高めるということで、暗号化ソフトを探しています。外部にCD等の媒体にデータを入れて持ち出す場合、万が一他人に開かれないように暗号化したいと考えています。フリーソフトもいっぱいあるようですが、会社で使用しますので購入して使用出来るような何かいいソフトご存知の方いらっしゃいましたら教えていただけないでしょうか?  それと、パソコンの取扱規定を作成しないといけなくなりました。(例えば、勝手にソフトをインストールしてはいけないとか)何か例があるURLとかを教えていただければありがたいかと思います。また、雛形等がありましたら非常にうれしいです。  分かる方いらっしゃいましたら教えてください。お願いします。

  • スーパーマリオアドバンス4 クリアしたんですけど・・・。

    こんにちは。 表記のとおり、マリオアドバンス4をクリアしました。 これで、どの面にもいけるようになったんですけど、ここから次は何をすればいいのでしょうか?? 中古で買ったので前の人のデータがのこってるんですけど、前の人のセーブデータは星がついていますが、自分のクリアしたものにはついていません(90/90 のみ) お城に行っても平和になったといわれるだけ。 謎なのが、5面のみ『OK』で、ほかの面は『clear』となっていました。でも、5面でクリアしてない面はないし・・・。 カードEは持っていません。 そうなると、これにておしまいでしょうか。

  • C言語 教えて下さい!!!

    教えてください!! data01.txt というテストの得点が書き込んであるテキストファイルから得点を読み込んで、得点順に並べ替えて表示させるプログラミングなんですがコンパイルは成功します。 しかし、実行してみると全く違う結果になってしまいます。 どこが間違っているのか指摘してください。 #include <stdio.h> /* 構造体の宣言 */ struct data { int score; int rank; }d; /* 関数 */ void rank(struct data *x, int n) { int i, j; for ( i=0; i<n; i++) x[i].rank = 1; for ( i=0; i<n; i++) for ( j=0; j<n; j++) if(x[i].score < x[j].score) x[i].rank++; } /* main文 */ int main(void) { int a; struct data x[50]; /* ファイルから得点を読み込む */ FILE *fp; fp = fopen("data01.txt", "r"); for ( a=0; a<50; a++) x[a] = atoi(getc(fp); fclose(fp); /* 順位付け */ a = 50; rank(x,a); printf("Rank Score\n"); for ( a=0; a<50; a++) printf("%d %d\n", x[a].rank, x[a].score); return 0; } ちなみに data.txt は 左側の列は番号 右側の列が得点 1 50 2 62 3 73 4 42 5 99 6 10 7 68 8 54 9 87 10 98 11 54 12 30 13 15 14 60 15 78 16 98 17 65 18 75 19 32 20 99 21 80 22 64 23 52 24 31 25 99 26 10 27 20 28 5 29 65 30 53 31 54 32 35 33 45 34 23 35 26 36 97 37 88 38 99 39 56 40 42 41 32 42 56 43 56 44 54 45 0 46 54 47 80 48 99 49 54 50 56

  • 大きな数の剰余

    現在、暗号に関するプログラムを作っていて、大きな数の剰余を するところで悩んでます。 ここでいう大きな数は2乗や3乗やその他の手続きを経てintやunsigned intで扱える数値を超えているものです。 演算子%も扱える数値が決まっているようでうまくいかないです。 型をdoubleにして割る数をひたすら引いていけば答えは出ますが 効率がいいとはいえません。 型、アルゴリズムという観点で大きな数の剰余はどのようにすれば できるのか教えてください。よろしくお願いします。

  • blowfishの実装について

    はじめまして! 現在暗号化アルゴリズムであるblowfishを実装しようと試みている最中なのですが、いまいちうまくいきません。 http://www.di-mgt.com.au/crypto.html 上記のページにあるフリーのサンプルを利用し、 ・任意の文字列を暗号化してファイルに吐き出し ・ファイルから暗号化した文字列を取り出して複合化 という処理をしようとしているのですが、複合化がうまくいきません。 暗号化はサンプルアプリと同じ結果になるのでうまくいっているようです。 サンプルは暗号化した文字列変数をそのまま複合化しているのですが、そこにポイントがありそうなことまではわかりました。 処理単位が8ビットらしいのですが、当方、いかんせん英語がからっきしダメなことと、VB自体にそれほど精通していないので全く先に進みません。 どなたかご教授いただけないでしょうか? VBのサンプルや日本語での解説のあるサイト、書籍の紹介などでも結構です。 よろしくお願い致します。

専門家に質問してみよう