提交 b5df1057 编写于 作者: F feilong

改进4题

上级 68ecab5d
......@@ -4,4 +4,5 @@
__pycache__
*.pyc
*.zip
*.out
\ No newline at end of file
*.out
*.pdf
\ No newline at end of file
{
"one_line": {
"print(\"\".join(result))": [
"print(\",\".join(result))",
"print(result)"
],
"result.append(token[\"key\"])": [
"result.append(token)"
]
},
"source": "class.py",
"source": "class.md",
"depends": [],
"exercise_id": 26,
"type": "code_options"
......
# Alice、Bob 和他们的朋友们
密码学家 Rivest、Shamir、Adleman 于1977年4月撰写了一篇论文《数字签名与公钥密码学》(On Digital Signatures and Public-Key Cryptosystems),并投稿至了一个期刊上,不过很遗憾这篇论文被拒稿了。随后他们修改了论文,并将论文重新命名为《一种实现数字签名和公钥密码系统的方法》(A Method of Obtaining Digital Signatures and Public-Key Cryptosystems),最终于1978年2月成功发表于顶级期刊《ACM通信》(Communications of the ACM)。在这篇论文中,三位密码学家嫌弃使用A、B两个字母代表角色太无聊,就用Alice和Bob来代替A和B。
在随后的几十年里密码学界又新增了很多著名人物。布鲁斯·施奈尔所著的《应用密码学》(Applied Cryptography)里详细列举了这些人物:
```python
crypto_roles = [
'爱丽丝(Alice)是信息发送者。',
'与鲍伯(Bob)是信息接受者。通例上,爱丽丝希望把一条消息发送给鲍伯。',
'卡罗尔或查利(Carol或Charlie)是通信中的第三位参加者。',
'戴夫(Dave)是通信中的第四位参加者。',
'伊夫(Eve)是一位偷听者(eavesdropper),但行为通常是被动的。她拥有偷听的技术,但不会中途篡改发送的消息。在量子密码学中,伊夫也可以指环境(environment)。',
'艾萨克(Isaac)是互联网服务提供者 (ISP)。',
'伊凡(Ivan)是发行人,使用于商业密码学中。',
'贾斯汀(Justin)是司法(justice)机关。',
'马洛里(Mallory)是一位恶意攻击者(malicious attacker)。与伊夫不同的是,马洛里会篡改发送的消息。对付马洛里所需的信息安全技术比对伊夫的高出很多。有时亦会叫作马文(Marvin)或马利特(Mallet)。',
'马提尔达(Matilda)是一位商人(merchant),用于电子商务。',
'奥斯卡(Oscar)是敌人,通常与马洛里一样。',
'帕特(Pat)或佩吉(Peggy)是证明者(prover),维克托(Victor)是验证者(verifier)。两人会证实一项事件是否有实际进行,多使用于零知识证明。',
'普特(Plod或Officer Plod)是执法官员。名称来自伊妮·布来敦所著的儿童文学《诺弟》(Noddy)中的角色“普特先生”。',
'史蒂夫(Steve)代指隐写术(Steganography)。',
'特伦特(Trent)是一位可信赖的仲裁人(trusted arbitrator),中立的第三者,根据存在的协议而判断。',
'特鲁迪(Trudy)是侵入者(intruder),等同马洛里。',
'沃特(Walter)是看守人(warden)。根据已存在的协议而保护爱丽丝和鲍伯。',
'佐伊(Zoe)通常是一个安全协议中的最后参与者。'
]
```
Python 是一门多范式编程语言,其中包括面向对象编程。
首先,我们用 `Python 类(class)` 定义一个密码城邦人物类型:
```python
class CryptographyPeople:
def __init__(self, name_cn, name_en, role, desc):
self.name_cn = name_cn
self.name_en = name_en
self.role = role
self.desc = desc
```
其次,我们添加一个简易的密码城邦人物解析器,它的作用是将类似`'马提尔达(Matilda)是一位商人(merchant),用于电子商务。',`这样的`人物剧本`解析成`CryptographyPeople`,创建一个密码城邦人物:
```python
class SimpleCryptographyPeopleParser:
def __init__(self, text) -> None:
self.text = text
def parse(self, desc):
# 解析名字部分
name_cn, name_en, rest = self.parse_name(desc)
# 解析角色部分
role, rest = self.parse_role(rest)
# 解析描述不符
desc = self.parse_desc(rest)
# 创建密码城邦人物
people = CryptographyPeople(name_cn, name_en, role, desc)
return people
def parse_name(self, text):
# 解析名字部分
index = text.find('是')
name, rest = text[0:index], text[index+1:]
# 解析中英文名字
start = name.find('(')
end = name.find(')')
name_cn = name[0:start]
name_en = name[start+1:end]
return name_cn.strip(), name_en.strip(), rest
def parse_role(self, text):
index1 = text.find('。')
index2 = text.find(',')
index = 0
if index1 > 0 and index2 > 0:
index = min(index1, index2)
else:
index = max(index1, index2)
role, rest = text[0:index], text[index+1:len(text)-1]
# 去除冗余量词
counts = ['一名', '一位', '一个']
for count in counts:
role = role.replace(count, '')
return role.strip(), rest.strip()
def parse_desc(self, name_cn, name_en, role, rest):
desc = rest
if desc:
# 识别自我主语
self_list = [name_cn, '他', '她']
for self_item in self_list:
desc = desc.replace(self_item, '我')
else:
# 补充默认描述
desc = '很高兴认识你'
```
最后,我们希望创建一个密码城邦,它包含 `add``introduce` 两个方法:
```python
class CryptographyCity:
def __init__(self):
self.peoples = []
def add(self, text):
parser = SimpleCryptographyPeopleParser(text)
people = parser.parse(text)
self.peoples.append(people)
# TODO(YOU): 请在此实现 introduce 方法
```
最终,我们可以构建起密码城邦,并让市民们全部自报家门:
```python
if __name__ == '__main__':
crypto_roles = ...
city = CryptographyCity()
for crypto_role in crypto_roles:
city.add(crypto_role)
city.introduce()
```
密码城邦人物的自我介绍如下:
```bash
爱丽丝(Alice): 密码学家说我是一位信息发送者,很高兴认识你。
鲍伯(Bob): 密码学家说我是一位信息接受者,通例上,爱丽丝希望把一条消息发送给我。
卡罗尔或查利(Carol或Charlie): 密码学家说我是一位通信中的第三位参加者,很高兴认识你。
戴夫(Dave): 密码学家说我是一位通信中的第四位参加者,很高兴认识你。
伊夫(Eve): 密码学家说我是一位偷听者(eavesdropper),但行为通常是被动的。我拥有偷听的技术,但不会中途篡改发送的消息。在量子密码学中,我也可以指环境(environment)。
艾萨克(Isaac): 密码学家说我是一位互联网服务提供者 (ISP),很高兴认识你。
伊凡(Ivan): 密码学家说我是一位发行人,使用于商业密码学中。
贾斯汀(Justin): 密码学家说我是一位司法(justice)机关,很高兴认识你。
马洛里(Mallory): 密码学家说我是一位恶意攻击者(malicious attacker),与伊夫不同的是,我会篡改发送的消息。对付我所需的信息安全技术比对伊夫的高出很多。有时亦会叫作马文(Marvin)或马利特(Mallet)。
马提尔达(Matilda): 密码学家说我是一位商人(merchant),用于电子商务。
奥斯卡(Oscar): 密码学家说我是一位敌人,通常与马洛里一样。
帕特(Pat): 密码学家说我是一位证明者(prover),维克托(Victor)是验证者(verifier)。两人会证实一项事件是否有实际进行,多使用于零知识证明。
普特(Plod或Officer Plod): 密码学家说我是一位执法官员,名称来自伊妮·布来敦所著的儿童文学《诺弟》(Noddy)中的角色“我先生”。
史蒂夫(Steve): 密码学家说我是一位隐写术(Steganography),很高兴认识你。
特伦特(Trent): 密码学家说我是一位可信赖的仲裁人(trusted arbitrator),中立的第三者,根据存在的协议而判断。
特鲁迪(Trudy): 密码学家说我是一位侵入者(intruder),等同马洛里。
沃特(Walter): 密码学家说我是一位看守人(warden),根据已存在的协议而保护爱丽丝和鲍伯。
佐伊(Zoe): 密码学家说我是一位安全协议中的最后参与者,很高兴认识你。
```
请找出以下对类`CryptographyCity`的方法`introduce`的实现中,<span style="color:red">不正确</span>的选项。
## template
```python
class CryptographyPeople:
def __init__(self, name_cn, name_en, role, desc):
self.name_cn = name_cn
self.name_en = name_en
self.role = role
self.desc = desc
class SimpleCryptographyPeopleParser:
def __init__(self, text) -> None:
self.text = text
def parse(self, desc):
# 解析名字部分
name_cn, name_en, rest = self.parse_name(desc)
# 解析角色部分
role, rest = self.parse_role(name_cn, name_en, rest)
# 解析描述不符
desc = self.parse_desc(name_cn, name_en, role, rest)
# 创建密码城邦人物
people = CryptographyPeople(name_cn, name_en, role, desc)
return people
def parse_name(self, text):
# 解析名字部分
index = text.find('是')
name, rest = text[0:index], text[index+1:]
# 解析中英文名字
start = name.find('(')
end = name.find(')')
name_cn = name[0:start]
name_en = name[start+1:end]
return name_cn.strip(), name_en.strip(), rest
def parse_role(self, name_cn, name_en, text):
index1 = text.find('。')
index2 = text.find(',')
index = 0
if index1 > 0 and index2 > 0:
index = min(index1, index2)
else:
index = max(index1, index2)
role, rest = text[0:index], text[index+1:len(text)-1]
# 去除冗余量词
counts = ['一名', '一位', '一个']
for count in counts:
role = role.replace(count, '')
return role.strip(), rest.strip()
def parse_desc(self, name_cn, name_en, role, rest):
desc = rest
if desc:
# 识别自我主语
self_list = [name_cn, '他', '她']
for self_item in self_list:
desc = desc.replace(self_item, '我')
else:
# 补充默认描述
desc = '很高兴认识你'
return desc
class CryptographyCity:
def __init__(self):
self.peoples = []
def add(self, text):
parser = SimpleCryptographyPeopleParser(text)
people = parser.parse(text)
self.peoples.append(people)
def introduce(self):
for people in self.peoples:
info = f'{people.name_cn}({people.name_en}): 密码学家说我是一位{people.role}{people.desc}。'
print(info)
if __name__ == '__main__':
crypto_roles = [
'爱丽丝(Alice)是信息发送者。',
'鲍伯(Bob)是信息接受者。通例上,爱丽丝希望把一条消息发送给鲍伯。',
'卡罗尔或查利(Carol或Charlie)是通信中的第三位参加者。',
'戴夫(Dave)是通信中的第四位参加者。',
'伊夫(Eve)是一位偷听者(eavesdropper),但行为通常是被动的。她拥有偷听的技术,但不会中途篡改发送的消息。在量子密码学中,伊夫也可以指环境(environment)。',
'艾萨克(Isaac)是互联网服务提供者 (ISP)。',
'伊凡(Ivan)是发行人,使用于商业密码学中。',
'贾斯汀(Justin)是司法(justice)机关。',
'马洛里(Mallory)是一位恶意攻击者(malicious attacker)。与伊夫不同的是,马洛里会篡改发送的消息。对付马洛里所需的信息安全技术比对伊夫的高出很多。有时亦会叫作马文(Marvin)或马利特(Mallet)。',
'马提尔达(Matilda)是一位商人(merchant),用于电子商务。',
'奥斯卡(Oscar)是敌人,通常与马洛里一样。',
'帕特(Pat)或佩吉(Peggy)是证明者(prover),维克托(Victor)是验证者(verifier)。两人会证实一项事件是否有实际进行,多使用于零知识证明。',
'普特(Plod或Officer Plod)是执法官员。名称来自伊妮·布来敦所著的儿童文学《诺弟》(Noddy)中的角色“普特先生”。',
'史蒂夫(Steve)是隐写术(Steganography)。',
'特伦特(Trent)是一位可信赖的仲裁人(trusted arbitrator),中立的第三者,根据存在的协议而判断。',
'特鲁迪(Trudy)是侵入者(intruder),等同马洛里。',
'沃特(Walter)是看守人(warden),根据已存在的协议而保护爱丽丝和鲍伯。',
'佐伊(Zoe)通常是一个安全协议中的最后参与者。'
]
city = CryptographyCity()
for crypto_role in crypto_roles:
city.add(crypto_role)
city.introduce()
```
## 答案
```python
class CryptographyCity:
def __init__(self):
self.peoples = []
def add(self, text):
parser = SimpleCryptographyPeopleParser(text)
people = parser.parse(text)
self.peoples.append(people)
def introduce():
for people in peoples:
say(people)
def say(people):
info = f'{people.name_cn}({people.name_en}): 密码学家说我是一位{people.role}{people.desc}。'
print(info)
```
## 选项
### for 语句实现
```python
class CryptographyCity:
def __init__(self):
self.peoples = []
def add(self, text):
parser = SimpleCryptographyPeopleParser(text)
people = parser.parse(text)
self.peoples.append(people)
def introduce(self):
for people in self.peoples:
self.say(people)
def say(self, people):
info = f'{people.name_cn}({people.name_en}): 密码学家说我是一位{people.role}{people.desc}。'
print(info)
```
### while语句实现
```python
class CryptographyCity:
def __init__(self):
self.peoples = []
def add(self, text):
parser = SimpleCryptographyPeopleParser(text)
people = parser.parse(text)
self.peoples.append(people)
def introduce(self):
i=0
while i<len(self.peoples):
people = self.peoples[i]
self.say(people)
i+=1
def say(self, people):
info = f'{people.name_cn}({people.name_en}): 密码学家说我是一位{people.role}{people.desc}。'
print(info)
```
### 列表表达式
```python
class CryptographyCity:
def __init__(self):
self.peoples = []
def add(self, text):
parser = SimpleCryptographyPeopleParser(text)
people = parser.parse(text)
self.peoples.append(people)
def introduce(self):
[self.say(people) for people in self.peoples]
def say(self, people):
info = f'{people.name_cn}({people.name_en}): 密码学家说我是一位{people.role}{people.desc}。'
print(info)
```
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:面向对象
# 描述:使用 Python Class 组织代码,输出“猴子在苹果树下打架”
# 标题:Alice、Bob 和他们的朋友们
# 描述:密码学著名人物
# [1] https://www.zhihu.com/question/63306763
# [2] https://en.wikipedia.org/wiki/Alice_and_Bob
class Monkey(object):
def __init__(self) -> None:
super().__init__()
self.tokens = []
def add_action_token(self, token):
self.tokens.append({"key": token})
class CryptographyPeople:
def __init__(self, name_cn, name_en, role, desc):
self.name_cn = name_cn
self.name_en = name_en
self.role = role
self.desc = desc
def play(self):
result = []
for token in self.tokens:
result.append(token["key"])
print("".join(result))
class SimpleCryptographyPeopleParser:
def __init__(self, text) -> None:
self.text = text
def main():
m = Monkey()
m.add_action_token("猴子在")
m.add_action_token("苹果树下")
m.add_action_token("打架")
m.play()
def parse(self, desc):
# 解析名字部分
name_cn, name_en, rest = self.parse_name(desc)
# 解析角色部分
role, rest = self.parse_role(name_cn, name_en, rest)
# 解析描述不符
desc = self.parse_desc(name_cn, name_en, role, rest)
# 创建密码城邦人物
people = CryptographyPeople(name_cn, name_en, role, desc)
return people
def parse_name(self, text):
# 解析名字部分
index = text.find('是')
name, rest = text[0:index], text[index+1:]
# 解析中英文名字
start = name.find('(')
end = name.find(')')
name_cn = name[0:start]
name_en = name[start+1:end]
return name_cn.strip(), name_en.strip(), rest
def parse_role(self, name_cn, name_en, text):
index1 = text.find('。')
index2 = text.find(',')
index = 0
if index1 > 0 and index2 > 0:
index = min(index1, index2)
else:
index = max(index1, index2)
role, rest = text[0:index], text[index+1:len(text)-1]
# 去除冗余量词
counts = ['一名', '一位', '一个']
for count in counts:
role = role.replace(count, '')
return role.strip(), rest.strip()
def parse_desc(self, name_cn, name_en, role, rest):
desc = rest
if desc:
# 识别自我主语
self_list = [name_cn, '他', '她']
for self_item in self_list:
desc = desc.replace(self_item, '我')
else:
# 补充默认描述
desc = '很高兴认识你'
return desc
class CryptographyCity:
def __init__(self):
self.peoples = []
def add(self, text):
parser = SimpleCryptographyPeopleParser(text)
people = parser.parse(text)
self.peoples.append(people)
def introduce(self):
for people in self.peoples:
info = f'{people.name_cn}({people.name_en}): 密码学家说我是一位{people.role}{people.desc}。'
print(info)
if __name__ == '__main__':
main()
crypto_roles = [
'爱丽丝(Alice)是信息发送者。',
'鲍伯(Bob)是信息接受者。通例上,爱丽丝希望把一条消息发送给鲍伯。',
'卡罗尔或查利(Carol或Charlie)是通信中的第三位参加者。',
'戴夫(Dave)是通信中的第四位参加者。',
'伊夫(Eve)是一位偷听者(eavesdropper),但行为通常是被动的。她拥有偷听的技术,但不会中途篡改发送的消息。在量子密码学中,伊夫也可以指环境(environment)。',
'艾萨克(Isaac)是互联网服务提供者 (ISP)。',
'伊凡(Ivan)是发行人,使用于商业密码学中。',
'贾斯汀(Justin)是司法(justice)机关。',
'马洛里(Mallory)是一位恶意攻击者(malicious attacker)。与伊夫不同的是,马洛里会篡改发送的消息。对付马洛里所需的信息安全技术比对伊夫的高出很多。有时亦会叫作马文(Marvin)或马利特(Mallet)。',
'马提尔达(Matilda)是一位商人(merchant),用于电子商务。',
'奥斯卡(Oscar)是敌人,通常与马洛里一样。',
'帕特(Pat)或佩吉(Peggy)是证明者(prover),维克托(Victor)是验证者(verifier)。两人会证实一项事件是否有实际进行,多使用于零知识证明。',
'普特(Plod或Officer Plod)是执法官员。名称来自伊妮·布来敦所著的儿童文学《诺弟》(Noddy)中的角色“普特先生”。',
'史蒂夫(Steve)是隐写术(Steganography)。',
'特伦特(Trent)是一位可信赖的仲裁人(trusted arbitrator),中立的第三者,根据存在的协议而判断。',
'特鲁迪(Trudy)是侵入者(intruder),等同马洛里。',
'沃特(Walter)是看守人(warden),根据已存在的协议而保护爱丽丝和鲍伯。',
'佐伊(Zoe)通常是一个安全协议中的最后参与者。'
]
city = CryptographyCity()
for crypto_role in crypto_roles:
city.add(crypto_role)
city.introduce()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册