-
Notifications
You must be signed in to change notification settings - Fork 1
145 lines (117 loc) · 5.19 KB
/
judge.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
name: OJ Judge
on:
issues:
types: [opened]
jobs:
judge:
runs-on: ubuntu-latest
if: contains(github.event.issue.title, '评测')
steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
pip install cryptography psutil
- name: Decrypt and Judge
id: judge
env:
PRIVATE_KEY: ${{ secrets.RSA_PRIVATE_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_CREATOR: ${{ github.event.issue.user.login }}
run: |
# 解析题目名称
PROBLEM_NAME=$(echo "${{ github.event.issue.title }}" | sed 's/评测//')
# 保存私钥
echo "$PRIVATE_KEY" > private.pem
# 解密提交的代码
echo "${{ github.event.issue.body }}" | base64 -d > encrypted_code
python3 -c "
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import base64
import os
with open('private.pem', 'rb') as f:
private_key = serialization.load_pem_private_key(f.read(), password=None)
with open('encrypted_code', 'rb') as f:
encrypted_data = f.read()
# 提取RSA加密的AES密钥(前256字节),IV(接下来的16字节)和加密数据
encrypted_key = encrypted_data[:256]
iv = encrypted_data[256:272]
encrypted_content = encrypted_data[272:]
# 解密AES密钥
aes_key = private_key.decrypt(
encrypted_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# 使用AES解密数据
cipher = Cipher(algorithms.AES(aes_key), modes.CBC(iv), backend=default_backend())
decryptor = cipher.decryptor()
decrypted_padded = decryptor.update(encrypted_content) + decryptor.finalize()
# 移除PKCS7 padding
pad_length = decrypted_padded[-1]
decrypted = decrypted_padded[:-pad_length]
content = decrypted.decode('utf-8')
username, lang, code = content.split('\n', 2)
issue_creator = os.environ['ISSUE_CREATOR']
if username.strip() != issue_creator:
with open('judge_result.txt', 'w') as f:
f.write('CHEATING')
else:
with open('solution.cpp', 'wb') as f:
f.write(code.encode('utf-8'))
with open('lang.txt', 'w') as f:
f.write(lang.strip())
with open('judge_result.txt', 'w') as f:
f.write('OK')
"
# 检查判定结果
JUDGE_RESULT=$(cat judge_result.txt)
if [ "$JUDGE_RESULT" = "CHEATING" ]; then
# 创建作弊标签
gh label create "CHEATING" --color "ff0000" || true
# 添加作弊标签和回复
gh issue edit ${{ github.event.issue.number }} --add-label "CHEATING"
gh issue comment ${{ github.event.issue.number }} --body "检测到代码抄袭行为!"
gh issue close ${{ github.event.issue.number }}
else
# 处理 list.txt,移除 \r 确保兼容性
sed -i 's/\r//' ./problems/list.txt
# 计算题目 ID
ID=$(grep -n "^$PROBLEM_NAME$" ./problems/list.txt | cut -d: -f1)
if [ -z "$ID" ]; then
echo "题目不存在: $PROBLEM_NAME" >&2
exit 1
fi
LANG=$(cat lang.txt)
# 运行评测
RESULT=$(python3 judge.py private.pem "problems/$ID" solution.cpp "$LANG")
# 回复结果
gh issue comment ${{ github.event.issue.number }} --body "$RESULT"
# 获取状态
STATUS=$(cat judge_status.txt)
# 确保标签存在
create_label_if_not_exists() {
local label=$1
local color=$2
gh label list | grep -q "^$label\s" || gh label create "$label" --color "$color"
}
# 为不同的标签设置不同的颜色
create_label_if_not_exists "AC" "0e8a16"
create_label_if_not_exists "MLE" "1e90ff"
create_label_if_not_exists "WA" "d93f0b"
create_label_if_not_exists "TLE" "ff69b4"
create_label_if_not_exists "CE" "808080"
# 添加标签
gh issue edit ${{ github.event.issue.number }} --add-label "$STATUS"
gh issue close ${{ github.event.issue.number }}
fi