7

ターンベースのビデオ ゲームのデータ転送の基礎として Pyramid を使用しています。クライアントは POST データを使用してアクションを提示し、GET を使用してシリアル化されたゲーム ボード データを取得します。ゲーム データには文字列が含まれることがありますが、ほとんどの場合、2 つの整数と 2 つのタプルです。

gamedata = (userid, gamenumber, (sourcex, sourcey), (destx, desty))

私の一般的なクライアント側フレームワークは、 Pickle 、base 64 への変換、urlencode の使用、および POST の送信でした。次に、サーバーは POST を受信し、単一項目のディクショナリをアンパックし、base64 をデコードしてから、データ オブジェクトをアンピクルします。

クラスや値が使えるのでPickleを使いたい。ゲーム データを POST フィールドとして送信しても、文字列しか得られません。

ただし、Pickle は安全ではないと見なされます。そこで、同じ目的を果たす pyYAML に目を向けました。を使用するyaml.safe_load(data)と、セキュリティ上の欠陥を公開することなくデータをシリアル化できます。ただし、safe_load は非常に安全です。無害なタプルやリストは、たとえ整数しか含まれていなくても、逆シリアル化することはできません。

ここに中間点はありますか?任意のコードの実行を同時に許可せずに Python 構造をシリアル化する方法はありますか?

私が最初に考えたのは、値の名前にアンダースコアを使用してタプルを再作成する送信関数と受信関数のラッパーを作成することでした。たとえば、送信すると辞書の値が に変換source : (x, y)されsource_0 : x, source_1: yます。私の 2 番目の考えは、それはあまり賢明な開発方法ではないということでした。

編集:これは JSON を使用した私の実装です... YAML や Pickle ほど強力ではないようですが、それでもセキュリティ ホールがあるのではないかと心配しています。

私が実験している間、クライアント側はもう少し目に見えて構築されました:

import urllib, json, base64

arbitrarydata = { 'id':14, 'gn':25, 'sourcecoord':(10,12), 'destcoord':(8,14)}

jsondata = json.dumps(arbitrarydata)
b64data = base64.urlsafe_b64encode(jsondata)
transmitstring = urllib.urlencode( [ ('data', b64data) ] )
urllib.urlopen('http://127.0.0.1:9000/post', transmitstring).read()

Pyramid Server はデータ オブジェクトを取得できます。

json.loads(base64.urlsafe_b64decode(request.POST['data'].encode('ascii')))

関係のない話ですが、この方法で POST データを使用することの許容性について他の意見を聞きたいです。現時点では、私のゲーム クライアントはブラウザー ベースではありません。

4

3 に答える 3

3

どうjsonですか?このライブラリは標準の Python ライブラリの一部であり、任意のコードを実行することなく、ほとんどの一般的なデータをシリアル化できます。

于 2012-10-07T16:52:50.443 に答える
3

colanderシリアライゼーションとデシリアライゼーションに使用してみませんか? Colander はオブジェクト スキーマを単純なデータ構造に、またはその逆に変換し、JSON を使用してこの情報を送受信できます。

例えば:

import colander

class Item(colander.MappingSchema):
    thing = colander.SchemaNode(colander.String(),
                                validator=colander.OneOf(['foo', 'bar']))
    flag = colander.SchemaNode(colander.Boolean())
    language = colander.SchemaNode(colander.String()
                                   validator=colander.OneOf(supported_languages)

class Items(colander.SequenceSchema):
    item = Item()

上記のセットアップでは、アイテム オブジェクトのリストを定義していますが、ゲーム固有のオブジェクトも簡単に定義できます。

逆シリアル化は次のようになります。

    items = Items().deserialize(json.loads(jsondata))

シリアル化は次のとおりです。

    json.dumps(Items().serialize(items))

Python オブジェクトを往復できるようにするだけでなく、シリアル化されたデータを検証して、スキーマに適合し、いじられていないことを確認します。

于 2012-10-07T16:53:32.640 に答える
0

JSON質問が具体的に酸洗いのクラスと値に言及していると思うので、ここで生が答えを提供するとは思いません。JSONストレートを使用してPythonクラスをシリアライズおよびデシリアライズできるとは思いませんが、pickleできます。

私はpickleほぼすべてのサーバー間通信に に基づくシリアライゼーション方式を使用していますが、常に非常に本格的な認証メカニズム (RSA 鍵ペアの照合など) が含まれています。ただし、それは信頼できるソースのみを扱うことを意味します。

信頼できないソースを絶対に扱う必要がある場合は、少なくとも、(@MartijnPieters が示唆するように) トランザクションを検証するスキーマを追加してみてください。信頼できないソースからの任意のピクルされたデータを操作する良い方法はないと思います。逆アセンブラでバイト文字列を解析し、信頼できるパターンのみを許可する (または信頼できないパターンをブロックする) などの操作を行う必要があります。に対してこれを行うことができるものは何も知りませんpickle

ただし、クラスが「十分に単純」である場合は、 を使用できる可能性があります。これはJSONEncoder、本質的に python クラスをJSONシリアル化できるものに変換し、検証します…

クラス JSON をシリアライズ可能にする方法

ただし、クラスを から派生させる必要があるという影響がありますJSONEncoder

于 2014-05-29T12:01:08.297 に答える