3

jar ファイルのグラフ同形性に関する質問に答えようとした結果、Python を使用して jar ファイルをグラフとして表現する方法について自然に議論が生じました。

問題: jar ファイルが与えられた場合、その中に含まれるファイルを読み取り、内容の表現を (a) データ構造および (b) グラフィックとして作成します。どちらも、次のようなさらなる研究と操作に適しています。たとえば、別の jar ファイルとの同型性を評価します。グラフでは、ディレクトリのツリーはルートおよびブランチ ノードであり、リーフ ノードとしてファイルで終わります。

答えを標準化するために、この OpenProcessing sketchverletphysics.jarからダウンロードしたファイルを使用します。

4

1 に答える 1

8

ソリューション

jar ファイルは基本的に圧縮されたアーカイブであるため、Python の標準ライブラリzipfileモジュールを使用してコンテンツを読み取り、jar のコンテンツの関係をテキストおよびグラフィック表現で準備します。

テキスト表現

質問に記載されているファイルの場合verletphysics.jar、以下のコードはこの内容のリストを生成します。

META-INF/
META-INF/MANIFEST.MF
toxi/
toxi/physics/
toxi/physics/behaviors/
toxi/physics/constraints/
toxi/physics2d/
toxi/physics2d/behaviors/
toxi/physics2d/constraints/
toxi/physics/ParticlePath.class
toxi/physics/ParticleString.class
toxi/physics/PullBackString.class
toxi/physics/VerletConstrainedSpring.class
toxi/physics/VerletMinDistanceSpring.class
toxi/physics/VerletParticle.class
toxi/physics/VerletPhysics.class
toxi/physics/VerletSpring.class
toxi/physics/behaviors/AttractionBehavior.class
toxi/physics/behaviors/ConstantForceBehavior.class
toxi/physics/behaviors/GravityBehavior.class
toxi/physics/behaviors/ParticleBehavior.class
toxi/physics/constraints/AxisConstraint.class
toxi/physics/constraints/BoxConstraint.class
toxi/physics/constraints/CylinderConstraint.class
toxi/physics/constraints/MaxConstraint.class
toxi/physics/constraints/MinConstraint.class
toxi/physics/constraints/ParticleConstraint.class
toxi/physics/constraints/PlaneConstraint.class
toxi/physics/constraints/SoftBoxConstraint.class
toxi/physics/constraints/SphereConstraint.class
toxi/physics2d/ParticlePath2D.class
toxi/physics2d/ParticleString2D.class
toxi/physics2d/PullBackString2D.class
toxi/physics2d/VerletConstrainedSpring2D.class
toxi/physics2d/VerletMinDistanceSpring2D.class
toxi/physics2d/VerletParticle2D.class
toxi/physics2d/VerletPhysics2D.class
toxi/physics2d/VerletSpring2D.class
toxi/physics2d/behaviors/AttractionBehavior.class
toxi/physics2d/behaviors/ConstantForceBehavior.class
toxi/physics2d/behaviors/GravityBehavior.class
toxi/physics2d/behaviors/ParticleBehavior2D.class
toxi/physics2d/constraints/AngularConstraint.class
toxi/physics2d/constraints/AxisConstraint.class
toxi/physics2d/constraints/CircularConstraint.class
toxi/physics2d/constraints/MaxConstraint.class
toxi/physics2d/constraints/MinConstraint.class
toxi/physics2d/constraints/ParticleConstraint2D.class
toxi/physics2d/constraints/RectConstraint.class
verletphysics.mf

キー

上記のパス名の各ノードが抽出され、次のようにコードによって一意の ID が与えられます。

 Index  File
     0  behaviors
     1  BoxConstraint.class
     2  MaxConstraint.class
     3  VerletParticle.class
     4  ParticleConstraint2D.class
     5  ConstantForceBehavior.class
     6  META-INF
     7  VerletMinDistanceSpring2D.class
     8  AxisConstraint.class
     9  AttractionBehavior.class
    10  physics2d
    11  VerletPhysics.class
    12  PullBackString.class
    13  VerletSpring.class
    14  VerletConstrainedSpring.class
    15  ParticleString2D.class
    16  verletphysics.mf
    17  ParticleBehavior2D.class
    18  ParticleString.class
    19  RectConstraint.class
    20  CylinderConstraint.class
    21  toxi
    22  VerletMinDistanceSpring.class
    23  VerletSpring2D.class
    24  VerletParticle2D.class
    25  ParticlePath2D.class
    26  CircularConstraint.class
    27  ParticlePath.class
    28  MinConstraint.class
    29  MANIFEST.MF
    30  ParticleConstraint.class
    31  GravityBehavior.class
    32  VerletPhysics2D.class
    33  SoftBoxConstraint.class
    34  ParticleBehavior.class
    35  VerletConstrainedSpring2D.class
    36  PlaneConstraint.class
    37  PullBackString2D.class
    38  SphereConstraint.class
    39  physics
    40  AngularConstraint.class
    41  constraints

グラフ

パス名は、 NetworkXを使用してこのネットワークに構築され、 matplotlibでプロットされるエッジに変換されます。

jar ファイルの内容のネットワーク グラフ

コード

import zipfile
import networkx as nx
import matplotlib.pyplot as plt

# Download the code from
# http://www.openprocessing.org/sketch/46757
# Unzip and find the jar file: verletphysics.jar
# This example uses that file for demo

def get_edges(fName):
    edges = []
    nodes = []

    jar = zipfile.ZipFile(fName, "r")
    for name in jar.namelist():
        print name # prints the list of files in the jar
        if name.endswith('/'): name = name[:-1]
        parts = name.split('/')
        nodes.extend( parts )
        if len(parts) > 1:
            edges += zip(nodes[:-1], nodes[1:]) 

    nodes = set(nodes)
    nodes = dict( zip(nodes, range(len(nodes)) ) )
    edges = [ (nodes[ edge[0] ], nodes[ edge[1] ])
              for edge in edges ]
    nodes = [ (index, label) for label, index in nodes.iteritems() ]
    nodes = sorted( nodes, key = lambda node: node[0] )
    return set( edges ), nodes

if __name__ == '__main__':
    fName = 'verletphysics.jar'
    edges, nodes = get_edges(fName)

    # print list of nodes
    # serving as a key to the graph
    print '%10s  %s' % ('Index', 'File')
    for node in nodes:
        print '%10s  %s' % (node[0], node[1])

    # Plot the network graph 
    G = nx.Graph()
    G.add_edges_from( edges )
    nx.draw_networkx(G, pos=nx.spring_layout(G))
    plt.axis('off')
    plt.show()
于 2012-06-11T18:29:12.437 に答える