簡易的なCryptreeの実装
code:Encryption.py
class Encryption:
def __init__(self):
self.key = Fernet.generate_key()
self.cipher_suite = Fernet(self.key)
def encrypt(self, data: str) -> bytes:
cipher_text = self.cipher_suite.encrypt(data.encode())
return cipher_text
def decrypt(self, cipher_text: bytes) -> str:
plain_text = self.cipher_suite.decrypt(cipher_text)
return plain_text.decode()
Cryptree構造のクラス作成
code:CryptreeNode.py
class CryptreeNode:
def __init__(self, node_type: str, name: str):
self.node_type = node_type
self.name = name
self.encryption = Encryption()
self.parent = None
self.children = {}
def add_child(self, child_node):
child_node.parent = self
self.data = None
def write_data(self, data: str):
if self.node_type =='file':
self.data = self.encryption.encrypt(data) #暗号化して保存 else:
raise Exception("Cannot write data to a directory")
def read_data(self) -> str:
if self.node_type == 'file':
return self.encryption.decrypt(self.data) #復号化して返す else:
raise Exception("Cannnot read data from a directory")
全体のルートノードと、各ノード間のリンク(暗号化キー)を管理する
code:Cryptree.py
class Cryptree:
def __init__(self, root: CryptreeNode):
self.root = root
# パス文字列を引数に取り、該当するノードを返す
def get_node(self, path: str) -> CryptreeNode:
path = path.strip('/').split('/')
return self.root
node = self.root
for part in path:
if part in node.children:
else:
return None
return node
ここでエラーが出ていた
chatGPT.icon現在、get_node メソッドは、指定されたパスのノードが存在しない場合、Noneを返すように設定されています。これは、create_node メソッドの中で get_node メソッドを使って親ノードを取得しようとしたとき、パスが存在しないと誤った結果を引き起こす可能性があります。
例えば、最初に '/' (root) へのパスを使ってノードを作成しようとした場合、get_node メソッドは '/' をstripして空のリストを返すため、forループは実行されず、結果として root ノードが返されます。しかし、この時点で任意の子ノードが存在しないため、root ノード自体が存在しないと解釈され、Noneが返されます。
これを修正するためには、get_node メソッドを修正して、パスが空(つまりrootを指している)の場合には直ちに root ノードを返すようにすると良いでしょう。以下に修正案を示します。
これが出ていた
if not path[0]: # If the path is root ('/')
return self.root
この二行を追加することで解消された
Node操作
code:operation.py
def create_node(self, path: str, node_type: str, name: str):
if parent is not None:
new_node = CryptreeNode(node_type, name)
parent.add_child(new_node)
return new_node
else:
raise Exception(f'NO such directory: {path}')
def delete_node(self, path: str):
node = self.get_node(path)
if node is not None:
parent = node.parent
if parent is not None:
else:
raise Exception("Cannot delete root node")
else:
raise Exception(f"No such file or directory: {path}")
def move_node(self, old_path: str, new_path: str):
if node is not None:
old_parent = node.parent
new_parent.add_child(node)
else:
raise Exception(f"No such directory: {new_path}")
else:
raise Exception(f"No such file or directory: {old_path}")
上記のコードが動くかどうかの実行
code:try.py
root = CryptreeNode('directory', 'root')
tree = Cryptree(root)
# 新しいディレクトリを作成
tree.create_node('/', 'directory', 'dir1')
# 新しいファイルを作成してデータを書き込む
file_node = tree.create_node('/dir1', 'file', 'file1')
file_node.write_data("Hello, Cryptree!")
# データを読み取る
print(file_node.read_data())
# ファイルを移動する
tree.move_node('/dir1/file1', '/')
# 以下、上記で定義した各クラスの後に追加する
if __name__ == "__main__":
# ルートディレクトリノードを作成
root = CryptreeNode('directory', 'root')
# Cryptreeを作成
tree = Cryptree(root)
# 新しいディレクトリをルートに作成
tree.create_node('/', 'directory', 'dir1')
# 新しいファイルを作成し、データを書き込む
file1 = tree.create_node('/dir1', 'file', 'file1')
file1.write_data('Hello, Cryptree!')
# データを読み取る
print(file1.read_data()) # 出力: 'Hello, Cryptree!'
実行結果
https://scrapbox.io/files/6465c7f88cb595001b82eabc.png
エラーでまくって死にかけた
: が抜けてたりも見てくれるから凄い助かったYudai.icon
ノード全てが異なる対称キーを持っていることになっている
ただただノードに対して鍵を割り当てただけ
それぞれが独立している