chore(i18n,learn): processed translations (#45504)

This commit is contained in:
camperbot
2022-03-23 19:52:04 +05:30
committed by GitHub
parent dbb7f309a7
commit 3add6077ad
162 changed files with 2383 additions and 826 deletions

View File

@@ -16,7 +16,7 @@ dashedName: anonymous-message-board
- 使用 [我们的 Replit 启动项目](https://replit.com/github/freeCodeCamp/boilerplate-project-messageboard)来完成你的项目。
- 使用一个你喜欢的站点生成器来完成项目。 需要确定包含了我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后将 URL 提交到 `Solution Link` 中。 此外,还可以项目源码提交到 `GitHub Link`
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后将 URL 提交到 `Solution Link` 中。 此外,还可以提交一个指向项目源码 `GitHub Link`
# --instructions--
@@ -116,49 +116,270 @@ async (getUserInput) => {
你可以向 `/api/replies/{board}` 发送一个 POST 请求,其中包括字段 `text``delete_password` & `thread_id`。 这将更新 `bumped_on` 日期到评论日期。 在主题的 `replies` 数组中,将保存一个对象,至少有 `_id``text``created_on``delete_password`& `reported` 这些属性。
```js
async (getUserInput) => {
const url = getUserInput('url');
const body = await fetch(url + '/api/threads/fcc_test');
const thread = await body.json();
const date = new Date();
const text = `fcc_test_reply_${date}`;
const delete_password = 'delete_me';
const thread_id = thread[0]._id;
const replyCount = thread[0].replies.length;
const data = { text, delete_password, thread_id };
const res = await fetch(url + '/api/replies/fcc_test', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.ok) {
const checkData = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
const parsed = await checkData.json();
try {
assert.equal(parsed.replies.length, replyCount + 1);
assert.equal(parsed.replies[0].text, text);
assert.equal(parsed._id, thread_id);
assert.equal(parsed.bumped_on, parsed.replies[0].created_on);
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
你可以向 `/api/threads/{board}` 发送一个 GET 请求。 返回的将是一个数组,包括论坛上最近的 10 个被回复的主题,及每个主题最新的 3 个回帖。 `reported``delete_password` 字段将不会被发送到客户端。
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/threads/fcc_test');
if (res.ok) {
const threads = await res.json();
try {
assert.equal(res.status, 200);
assert.isAtMost(threads.length, 10);
for (let i = 0; i < threads.length; i++) {
assert.containsAllKeys(threads[i], ["_id", "text", "created_on", "bumped_on", "replies"]);
assert.isAtMost(threads[i].replies.length, 3);
assert.notExists(threads[i].delete_password);
assert.notExists(threads[i].reported);
for (let j = 0; j < threads[i].replies.length; j++) {
assert.notExists(threads[i].replies[j].delete_password);
assert.notExists(threads[i].replies[j].reported);
}
}
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
你可以向 `/api/replies/{board}?thread_id={thread_id}` 发送一个 GET 请求。 返回的将是带有所有的回复的整个主题,不包括与之前测试相同的客户端字段。
```js
async (getUserInput) => {
const url = getUserInput('url');
let res = await fetch(url + '/api/threads/fcc_test');
const threads = await res.json();
const thread_id = threads[0]._id;
res = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
if (res.ok) {
const thread = await res.json();
try {
assert.equal(res.status, 200);
assert.isObject(thread);
assert.containsAllKeys(thread, ["_id", "text", "created_on", "bumped_on", "replies"]);
assert.isArray(thread.replies);
assert.notExists(thread.delete_password);
assert.notExists(thread.reported);
for (let i = 0; i < thread.replies.length; i++) {
assert.notExists(thread.replies[i].delete_password);
assert.notExists(thread.replies[i].reported);
}
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
你可以向 `/api/threads/{board}` 发送一个 DELETE 请求,并传递 `thread_id` & `delete_password` 来删除该线程。 返回的将是字符串 `incorrect password``success`
```js
async (getUserInput) => {
const url = getUserInput('url');
let res = await fetch(url + '/api/threads/fcc_test');
const threads = await res.json();
const thread_id = threads[0]._id;
let data = { thread_id, delete_password: "wrong_password" };
const res_invalid = await fetch(url + '/api/threads/fcc_test', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
data = { thread_id, delete_password: "delete_me" };
res = await fetch(url + '/api/threads/fcc_test', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.ok) {
const deleted = await res.text();
const not_deleted = await res_invalid.text();
try {
assert.equal(res.status, 200);
assert.equal(deleted, "success");
assert.equal(not_deleted, "incorrect password");
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
你可以向 `/api/replies/{board}` 发送一个 DELETE 请求,并传递 `thread_id``reply_id`& `delete_password`。 返回的将是字符串 `incorrect password``success`。 成功后,`reply_id` 的文本将更改为 `[deleted]`
```js
async (getUserInput) => {
const url = getUserInput('url');
const thread_data = {
text: "fcc_test_thread",
delete_password: "delete_me",
};
await fetch(`${url}/api/threads/fcc_test`, {
method: "POST",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(thread_data)
});
let res = await fetch(`${url}/api/threads/fcc_test`);
let threads = await res.json();
const thread_id = threads[0]._id;
const reply_data = { thread_id, text: "fcc_test_reply", delete_password: "delete_me" };
await fetch(`${url}/api/replies/fcc_test`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(reply_data)
});
res = await fetch(`${url}/api/threads/fcc_test`);
threads = await res.json();
const reply_id = threads[0].replies[0]._id;
const data = { thread_id, reply_id, delete_password: "delete_me" };
res = await fetch(url + '/api/replies/fcc_test', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.ok) {
const deleted = await res.text();
try {
assert.equal(res.status, 200);
assert.equal(deleted, "success");
res = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
const thread = await res.json();
assert.equal(thread._id, thread_id);
assert.equal(thread.replies[0]._id, reply_id);
assert.equal(thread.replies[0].text, "[deleted]");
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
你可以向 `/api/threads/{board}` 发送一个 PUT 请求,并传递 `thread_id`。 返回的将是字符串 `success``thread_id` 回复的 `reported` 值将改为 `true`
你可以向 `/api/threads/{board}` 发送一个 PUT 请求,并传递 `thread_id`。 返回的将是字符串 `reported``thread_id` 回复的 `reported` 值将改为 `true`
```js
async (getUserInput) => {
const url = getUserInput('url');
let res = await fetch(`${url}/api/threads/fcc_test`);
const threads = await res.json();
const report_id = threads[0]._id;
const data = { report_id };
res = await fetch(`${url}/api/threads/fcc_test`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.ok) {
const reported = await res.text();
try {
assert.equal(res.status, 200);
assert.equal(reported, "reported");
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
你可以通过向 `/api/replies/{board}` 发送 PUT 请求并传递 `thread_id` & `reply_id`。 返回的将是字符串 `success``reply_id``reported` 值将被改变为 `true`
你可以通过向 `/api/replies/{board}` 发送 PUT 请求并传递 `thread_id` & `reply_id`。 返回的将是字符串 `reported``reply_id``reported` 值将被改变为 `true`
```js
async (getUserInput) => {
const url = getUserInput('url');
let res = await fetch(`${url}/api/threads/fcc_test`);
const threads = await res.json();
const thread_id = threads[0]._id;
const reply_id = threads[0].replies[0]._id;
const data = { thread_id, reply_id };
res = await fetch(`${url}/api/replies/fcc_test`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.ok) {
const reported = await res.text();
try {
assert.equal(res.status, 200);
assert.equal(reported, "reported");
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
所有 10 项功能测试都已完成并通过。
```js
async (getUserInput) => {
const tests = await fetch(getUserInput('url') + '/_api/get-tests');
const parsed = await tests.json();
assert.isTrue(parsed.length >= 10);
parsed.forEach((test) => {
assert.equal(test.state, 'passed');
assert.isAtLeast(test.assertions.length, 1);
});
};
```
# --solutions--

View File

@@ -9,22 +9,74 @@ dashedName: port-scanner
# --description--
你将通过使用我们的 [Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-port-scanner) 来完成本项目。
我们仍在开发 Python 课程的交互式教学部分。 目前,你可以在 YouTube 上通过 freeCodeCamp.org 上传的一些视频学习这个项目相关的知识。
- [Python for Everybody 视频课程](https://www.freecodecamp.org/news/python-for-everybody/)14 小时)
- [Learn Python 视频课程](https://www.freecodecamp.org/news/learn-python-video-course/)10 小时)
# --instructions--
使用 Python 创建一个端口扫描器。
你可以访问 [Replit 上的完整项目描述和启动代码](https://replit.com/github/freeCodeCamp/boilerplate-port-scanner)
`port_scanner.py` 文件中,创建一个名为 `get_open_ports` 的函数,它接受一个 `target` 参数和一个 `port_range` 参数。 `target` 可以是 URL 或 IP 地址。 `port_range` 是两个数字的列表,表示要检查的端口范围的第一个和最后一个数字
在打开链接之后 fork 该项目。 根据 “README.md” 中的指示完成整个项目,然后在下面提交你的项目链接。
以下是如何调用该函数的示例:
Python 课程的交互式教学部分仍在开发当中。 目前freeCodeCamp YouTube 频道上的一些视频将会教授你这个项目要求的一些 Python 技能。
```py
get_open_ports("209.216.230.240", [440, 445])
get_open_ports("www.stackoverflow.com", [79, 82])
```
<ul>
<li>
<a href='https://www.freecodecamp.org/news/python-for-everybody/'>Python for Everybody 视频课程</a>14 小时)
</li>
<li>
<a href='https://www.freecodecamp.org/news/learn-python-basics-in-depth-video-course/'>Learn Python 视频课程</a>2 小时)
</li>
</ul>
该函数应返回给定范围内的开放端口列表。
`get_open_ports` 函数还应采用可选的第三个参数 `True` 来表示“详细”模式。 如果将其设置为 true则该函数应返回描述性字符串而不是端口列表。
以下是详细模式下应返回的字符串格式(`{}` 中的文本表示应显示的信息):
```bash
Open ports for {URL} ({IP address})
PORT SERVICE
{port} {service name}
{port} {service name}
```
你可以使用 `common_ports.py` 中的字典为每个端口获取正确的服务名称。
例如,如果函数是这样调用的:
```py
port_scanner.get_open_ports("scanme.nmap.org", [20, 80], True)
```
它应该返回以下内容:
```bash
Open ports for scanme.nmap.org (45.33.32.156)
PORT SERVICE
22 ssh
80 http
```
确保包含正确的间距和换行符。
如果传入 `get_open_ports` 函数的 URL 无效该函数应返回字符串“Error: Invalid hostname”。
如果传入 `get_open_ports` 函数的 IP 地址无效该函数应返回字符串“Error: Invalid IP address”。
## 开发
`port_scanner.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的代码。 单击“运行”按钮,`main.py` 将运行。
## 测试
这个项目的单元测试在 `test_module.py` 中。 为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
## 提交
复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--

View File

@@ -9,22 +9,51 @@ dashedName: sha-1-password-cracker
# --description--
你将通过使用我们的 [Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-SHA-1-password-cracker) 来完成本项目。
我们仍在开发 Python 课程的交互式教学部分。 目前,你可以在 YouTube 上通过 freeCodeCamp.org 上传的一些视频学习这个项目相关的知识。
- [Python for Everybody 视频课程](https://www.freecodecamp.org/news/python-for-everybody/)14 小时)
- [Learn Python 视频课程](https://www.freecodecamp.org/news/learn-python-video-course/)10 小时)
# --instructions--
密码不应以纯文本形式存储。 它们应该存储为哈希值,以防万一密码列表被泄露。 然而,并不是所有的哈希都是一样的。
在这个项目中,你将通过创建一个密码破解器来找出使用 SHA-1 散列的密码,从而了解到良好安全的重要性。
你可以访问 [Replit 上的完整项目描述和启动代码](https://replit.com/github/freeCodeCamp/boilerplate-SHA-1-password-cracker)
创建一个函数,该函数接受密码的 SHA-1 哈希值,如果它是使用的前 10,000 个密码之一,则返回该密码。 如果 SHA-1 哈希不是数据库中的密码,则返回“密码不在数据库中”
进入该链接后fork 该项目。 一旦你根据 “README.md” 中的说明完成了项目,请在下面提交你的项目链接
该函数应该对 `top-10000-passwords.txt` 中的每个密码进行散列,并将其与传递给函数的散列进行比较
我们仍在开发 Python 课程的交互式教学部分。 目前freeCodeCamp.org YouTube 频道上的一些视频可以教你这个项目所需的一些 Python 技能
该函数应采用名为 `use_salts` 的可选第二个参数。 如果设置为 true则文件 `known-salts.txt` 中的每个 salt 字符串,都应该在散列之前,和将它与传递给函数的哈希值进行比较之前,添加到 `top-10000-passwords.txt` 中的每个密码的之前和之后
<ul>
<li>
<a href='https://www.freecodecamp.org/news/python-for-everybody/'>Python for Everybody 视频课程</a>14 小时)
</li>
<li>
<a href='https://www.freecodecamp.org/news/learn-python-basics-in-depth-video-course/'>Learn Python 视频课程</a>2 小时)
</li>
</ul>
以下是一些用于测试该功能的散列密码:
- `b305921a3723cd5d70a375cd21a61e60aabb84ec` 应该返回 “sammy123”
- `c7ab388a5ebefbf4d550652f1eb4d833e5316e3e` 应该返回 “abacab”
- `5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8` 应该返回 “password”
以下是一些散列密码,用于在 `use_salts` 设置为 `True` 时测试该功能:
- `53d8b3dc9d39f0184144674e310185e41a87ffd5` 应该返回 “superman”
- `da5a4e8cf89539e66097acd2f8af128acae2f8ae` 应该返回 “q1w2e3r4t5”
- `ea3f62d498e3b98557f9f9cd0d905028b3b019e1` 应该返回 “bubbles1”
`hashlib` 库已经为你导入。 你应该在你的代码中使用它。 [在此了解更多关于 “hashlib” 的信息](https://docs.python.org/3/library/hashlib.html)
## 开发
`password_cracker.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的代码。 单击“运行”按钮,`main.py` 将运行。
## 测试
此项目的单元测试在 `test_module.py` 中。 为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
## 提交
复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--