“知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 分组加密器(encryption)
分组加密器(encryption)
题解点这里
#include<map>
#include<stack>
#include<vector>
#include<cstdio>
#include<iostream>
#define debug(x) cerr<<#x<<" "<<x<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int PLEN=;
const int SLEN=;
struct ptable_type{
int input_size,output_size;
int element[PLEN];
inline void Read(){
scanf("%d%d",&input_size,&output_size);
for(int i=;i<output_size;i++) scanf("%d",element+i);
}
};
struct sbox_type{
int input_size,output_size;
int element[<<SLEN];
inline void Read(){
scanf("%d%d",&input_size,&output_size);
for(int i=;i<(<<input_size);i++) scanf("%d",element+i);
}
};
struct lex_type{
string name;int type;ull value;
lex_type(string name="",int type=,ull value=):name(name),type(type),value(value){}
};
struct bs_var_type{
string name;int len;ull value;
bs_var_type(string name="",int len=,ull value=):name(name),len(len),value(value){}
vector<bs_var_type*> ch;
};
struct expr_type{
int id,type;ull value;
vector<int> bs_varp;
expr_type *expr1,*expr2;
};
struct gra_type{
int type,var,value,jmp;
vector<int> bs_varp;
expr_type* expr;
int st,ed;//lex[st] .. lex[ed]
};
int n,m;
ptable_type ptable[];
sbox_type sbox[]; string code;//store all characters of the code
int loop_var[];
vector<bs_var_type> bs_var;
vector<lex_type> lex;
vector<gra_type> gra;
stack<int> loop_pos;
vector<expr_type*> expr_ptr;
void ReadPtable(){
for(int i=;i<n;i++) ptable[i].Read();
}
void ReadSbox(){
for(int i=;i<m;i++) sbox[i].Read();
}
void ReadCode(){
char ch=getchar();
while(ch!='\n') ch=getchar();
for(bool meet_end=false;;){
code+=ch=getchar();
if(ch=='D') meet_end=true;
if(ch=='L') meet_end=false;
if(ch=='\n'&&meet_end) break;
}
}
int find_bs(string &name){
for(int i=,sz=bs_var.size();i<sz;i++) if(bs_var[i].name==name) return i;
return -;
}
char type5[]={'=','+','(',')','[',']','\n'};
string type0[]={"BEGIN","END","P","S","LOOP","ENDLOOP","SPLIT","MERGE"};
void lex_ana(){
string str;lex_type tmp;
for(int i=,j,codelen=code.length();i<codelen;str.clear()){
while(code[i]==','||code[i]==' '||code[i]=='\t') i++;
str+=code[i++];
if(str[]>='A'&&str[]<='Z'){//type 0
while(i<codelen&&code[i]>='A'&&code[i]<='Z') str+=code[i++];
for(j=;j<;j++) if(str==type0[j]) break;
tmp.name=str;tmp.type=;tmp.value=j;
lex.push_back(tmp);
}
else if(str[]>='a'&&str[]<='z'){//type 1 or 2
while(i<codelen&&code[i]>='a'&&code[i]<='z') str+=code[i++];
if(str.length()==){//type 1
lex.push_back(lex_type(str,,str[]-'a'));
}
else{//type 2
j=find_bs(str);
if(j==-){
j=bs_var.size();
bs_var.push_back(bs_var_type(str,,));
}
lex.push_back(lex_type(str,,j));
}
}
else if(str[]>=''&&str[]<=''){ //type 3
while(i<codelen&&code[i]>=''&&code[i]<='') str+=code[i++];
int strl=str.length(); ull x();
for(j=;j<strl;j++) x=x*+str[j]-'';
lex.push_back(lex_type(str,,x));
}
else if(str[]=='\"'){ //type 4
while(i<codelen&&code[i]>=''&&code[i]<='') str+=code[i++];
// str+=code[i++]);
i++;
int strl=str.length();ull x=;
for(j=;j<strl;j++) x=(x<<)|str[j]-'';
lex.push_back(lex_type(str,,x));
}
else{ //type 5
for(j=;j<;j++) if(str[]==type5[j]) break;
lex.push_back(lex_type(str,,j));
}
}
}
void init_bs_var(){
for(int i=,tmp;lex[i].name!="BEGIN";i+=){
tmp=lex[i].value;
bs_var[tmp].len=lex[i+].value;
bs_var[tmp].value=;
}
}
void get_bs_var(int l,int r,ull& value,vector<int>& bs_varp){
value=lex[l].value;
for(int i=l + ;i<r;i+=){
if(lex[i+].type==) bs_varp.push_back((int)(lex[i+].value)-); // 0..25 -> -26..-1
else bs_varp.push_back(lex[i+].value); // 0..63
}
}
expr_type* generate_expr(int l,int r){
expr_type* ptr=new expr_type;
ptr->id=expr_ptr.size();
expr_ptr.push_back(ptr);
ptr->expr1=NULL;ptr->expr2=NULL;ptr->value=;
int i=l;
for(int num=;i<=r;i++){
if(lex[i].name=="(") num++;
if(lex[i].name==")") num--;
if(lex[i].name=="+"&&num==) break;
}
if(i<=r){
ptr->type=;
ptr->expr1=generate_expr(l,i-);
ptr->expr2=generate_expr(i+,r);
return ptr;
}
if(lex[l].name=="P"||lex[l].name=="S"){
if(lex[l].name=="P") ptr->type=;else ptr->type=;
if(lex[l+].type==) ptr->value=lex[l+].value-;
else if(lex[l+].type==) ptr->value=lex[l+].value;
ptr->expr1=generate_expr(l+,r-);
return ptr;
}
if(lex[l].type==){
ptr->type=;
ptr->value=lex[l].value;
return ptr;
}
if(lex[l].type==){
ptr->type=;
get_bs_var(l,r,ptr->value,ptr->bs_varp);
return ptr;
}
}
void generate_gra(int l,int r){
gra_type tmp;
tmp.st=l;tmp.ed=r;
tmp.var=tmp.value=tmp.jmp=;
tmp.expr=NULL;
if(lex[l].name=="BEGIN"){
tmp.type=tmp.value=;
}
else if(lex[l].name=="END"){
tmp.type=;
tmp.value=;
}
else if(lex[l].name=="LOOP"){
tmp.type=;
tmp.var=lex[l+].value;
tmp.value=lex[l+].value;
tmp.jmp=lex[l+].value;
loop_pos.push(gra.size());
}
else if(lex[l].name=="ENDLOOP"){
int pos=loop_pos.top();loop_pos.pop();
tmp.type=;
tmp.var=gra[pos].var;
tmp.value=gra[pos].jmp;
gra[pos].jmp=;
tmp.jmp=pos+;
}
else if(lex[l].name=="SPLIT"){
tmp.type=;
tmp.value=lex[r-].value;
ull beta;
get_bs_var(l+,r-,beta,tmp.bs_varp);
tmp.var=beta;
}
else if(lex[l].name=="MERGE"){
tmp.type=;
ull beta;
get_bs_var(l+,r-,beta,tmp.bs_varp);
tmp.var=beta;
}
else if(lex[l].type==){ //assignment statement
int i=l;
while(i<=r&&lex[i].name!="=") i++;
tmp.type=;
ull beta;
get_bs_var(l,i-,beta,tmp.bs_varp);
tmp.var=beta;
tmp.expr=generate_expr(i+,r-);
}
gra.push_back(tmp);
}
void gra_ana(){
int i=,j,sz=lex.size();
for(i=;lex[i].name!="BEGIN";i++);
for(;i<sz;i=j+){
for(j=i;lex[j].name!="\n";j++);
generate_gra(i,j);
}
}
void bs_to_num(const string& str,ull& num){
num=;
for(int i=,sz=str.length();i<sz;i++) num=(num<<)|str[i]-'';
}
void num_to_bs(const ull& num,string& str,int size=PLEN){
str.clear();
for(ull tmp=1ull<<size-;tmp;tmp>>=) if(num&tmp) str+='';else str+='';
}
string int_to_str(int i){
string str;
stack<char>s;
if(i==){str="";return str;}
if(i<) str+='-',i=-i;
for(;i>;i/=) s.push((i%)+'');
while(!s.empty()) str+=s.top(),s.pop();
return str;
}
bs_var_type* find_bs_varp(ll pos,const vector<int>& bs_varp){
bs_var_type* ptr=&bs_var[pos];//?????
for(int i=,sz=bs_varp.size();i<sz;i++){
int j=bs_varp[i];
if(j<) j=loop_var[j+];
ptr=ptr->ch[j];
}
return ptr;
}
ull cal_expr(expr_type* ptr){
if(ptr->type==) return find_bs_varp(ptr->value,ptr->bs_varp)->value;
else if(ptr->type==) return ptr->value;
else if(ptr->type==) return cal_expr(ptr->expr1)^cal_expr(ptr->expr2);
else if(ptr->type==){
ull tmp=cal_expr(ptr->expr1);
ll j=ptr->value;
if(j<) j=loop_var[j+];
string sin,sout;
num_to_bs(tmp,sin,ptable[j].input_size);
for(int i=;i<ptable[j].output_size;i++)
sout.push_back(sin[ptable[j].element[i]]);
bs_to_num(sout,tmp);
return tmp;
}
else if(ptr->type==){
ull tmp=cal_expr(ptr->expr1);
ll j=ptr->value;
if(j<) j=loop_var[j+];
return sbox[j].element[tmp];
}
}
ull encrypt(ull state,ull key){
for(int now=;;){
if(gra[now].type==){
if(gra[now].value==){ //BEGIN
bs_var[].value=state;
bs_var[].value=key;
for(int i=;i<bs_var.size();i++) bs_var[i].value=;
now++;
}
else return bs_var[].value; //END
}
else if(gra[now].type==){
bs_var_type* ptr=find_bs_varp(gra[now].var,gra[now].bs_varp);
ptr->value=cal_expr(gra[now].expr);
now++;
}
else if(gra[now].type==){
loop_var[gra[now].var]=gra[now].value;
now++;
}
else if(gra[now].type==){
loop_var[gra[now].var]++;
if(loop_var[gra[now].var]>gra[now].value) now++;
else now=gra[now].jmp;
}
else if(gra[now].type==){
bs_var_type* ptr=find_bs_varp(gra[now].var,gra[now].bs_varp);
int tmp=gra[now].value;
int chlen=ptr->len / tmp;
for(int i=;i<tmp;i++){
bs_var_type* chptr=new bs_var_type;
chptr->len=chlen;
chptr->name=ptr->name+"["+int_to_str(i)+"]";
chptr->value=;
ptr->ch.push_back(chptr);
}
ull beta=(1ull<<chlen)-;
for(int i=tmp-;~i;i--){
ptr->ch[i]->value=ptr->value & beta;
ptr->value=ptr->value>>chlen;
}
now++;
}
else if(gra[now].type==){
bs_var_type* ptr=find_bs_varp(gra[now].var,gra[now].bs_varp);
int tmp=ptr->ch.size();
int chlen=ptr->len / tmp;
ptr->value=;
for(int i=;i<tmp;i++){
bs_var_type* chptr=ptr->ch[i];
ptr->value=(ptr->value<<chlen)|chptr->value;
delete chptr;
}
ptr->ch.clear();
now++;
}
}
}
void InitTaskA(){
scanf("%d%d",&n,&m);
ReadPtable();
ReadSbox();
ReadCode();
}
void SolveTaskA(){
lex_ana();
init_bs_var();
gra_ana();
int k; ull state,key; string str1,str2;
scanf("%d",&k);
for(int i=;i<k;i++){
cin>>str1>>str2;
bs_to_num(str1,state);
bs_to_num(str2,key);
num_to_bs(encrypt(state,key),str1,bs_var[].len);
puts(str1.c_str());
}
}
void taskB_init(){
code="state(32)\n";
code += "key(12)\n";
code += "dkey(16)\n";
code += "tmp(32)\n";
code += "BEGIN\n";
code += "SPLIT(dkey,4)\n";
code += "SPLIT(key,3)\n";
code += "dkey[0]=key[0]\n";
code += "dkey[1]=key[1]\n";
code += "dkey[2]=key[2]\n";
code += "dkey[3]=key[0] + key[1] + key[2]\n";
code += "MERGE(key)\n";
code += "MERGE(dkey)\n";
code += "LOOP i 1 16\n";
code += "dkey=P[2](dkey)\n";
code += "tmp=state\n";
code += "SPLIT(state,2)\n";
code += "SPLIT(tmp,2)\n";
code += "state[0]=tmp[1]\n";
code += "tmp[1]=tmp[1] + dkey\n";
code += "SPLIT(tmp[1],4)\n";
code += "LOOP j 0 3\n";
code += "tmp[1][j]=S[0](tmp[1][j])\n";
code += "ENDLOOP\n";
code += "MERGE(tmp[1])\n";
code += "state[1]=tmp[0] + P[0](tmp[1])\n";
code += "MERGE(state)\n";
code += "MERGE(tmp)\n";
code += "dkey=P[1](dkey)\n";
code += "ENDLOOP\n";
code += "tmp=state\n";
code += "SPLIT(state,2)\n";
code += "SPLIT(tmp,2)\n";
code += "state[0]=tmp[1]\n";
code += "state[1]=tmp[0]\n";
code += "MERGE(state)\n";
code += "MERGE(tmp)\n";
code += "END\n";
n=;
m=;
ptable[].input_size=;
ptable[].output_size=;
ptable[].input_size=;
ptable[].output_size=;
ptable[].input_size=;
ptable[].output_size=;
sbox[].input_size=;
sbox[].output_size=;
int p0[]={, , , , , , , , , , , , , , , };
int p1[]={, , , , , , , , , , , , , , , };
int p2[]={, , , , , , , , , , , , , , , };
int s0[]={, , , , , , , , , , , , , , , };
for(int i=;i<;i++){
ptable[].element[i]=p0[i];
ptable[].element[i]=p1[i];
ptable[].element[i]=p2[i];
sbox[].element[i]=s0[i];
}
}
void solve_taskB(){
lex_ana();
init_bs_var();
gra_ana();
ull state, ans, tmp;
string str1, str2;
int key1,key2;
map<ull,int> h;
cin >> str1 >> str2;
bs_to_num(str1,state);
bs_to_num(str2,ans);
for(int i=;i<;i++){
tmp=encrypt(state,i);
h[tmp]=i;
}
int p1[]={, , , , , , , , , , , , , , , };
int p2[]={, , , , , , , , , , , , , , , };
for(int i=;i<;i++){
ptable[].element[i]=p1[i];
ptable[].element[i]=p2[i];
}
for(int i=;i<;i++){
tmp=encrypt(ans,i);
if(h.find(tmp)==h.end()) continue;
key1=h[tmp];
key2=i;
num_to_bs(key1,str1,);
num_to_bs(key2,str2,);
cout << "YES" << endl;
cout << str1 << endl;
cout << str2 << endl;
return;
}
cout << "NO" << endl;
}
char task_id[];
int main(){
freopen("encryption.in","r",stdin);
freopen("encryption.out","w",stdout);
scanf("%s",task_id);
if(task_id[]=='A'){
InitTaskA();
SolveTaskA();
}
else{
// puts("NO");//pass 3 points
taskB_init();
solve_taskB();
}
fclose(stdin);fclose(stdout);
return ;
}
“知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 分组加密器(encryption)的更多相关文章
- “知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 绝地求生(battleground)
/* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-ts ...
- “知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 贪心算法(greedy)
--> 贪心算法 1)题解 • 分别用V0.V1和V>=2表示度为0.1以及至少为2的顶点集合 • 对于每个顶点,维护三个属性: • degree ...
- 中国大学生计算机系统与程序设计竞赛 CCF-CCSP-2016 选座( ticket_chooser )
选座( ticket_chooser ) 不会正解,欢迎讨论 //60分 #include<cstdio> #define max(a,b) (a)>(b)?a:b #define ...
- 中国大学生计算机系统与程序设计竞赛 CCF-CCSP-2017 串行调度(serial)
串行调度(serial) 除等价条件, 根据题意设置限制条件,然后求字典序最小拓扑序. 简洁版 #include<bits/stdc++.h> using namespace std; ; ...
- "字节跳动杯"2018中国大学生程序设计竞赛-女生专场 Solution
A - 口算训练 题意:询问 $[L, R]$区间内 的所有数的乘积是否是D的倍数 思路:考虑分解质因数 显然,一个数$x > \sqrt{x} 的质因子只有一个$ 那么我们考虑将小于$\sqr ...
- "字节跳动杯"2018中国大学生程序设计竞赛-女生专场
口算训练 #include <iostream> #include <algorithm> #include <cstring> #include <cstd ...
- “纽劢科技杯”第十六届同济大学程序设计竞赛暨上海邀请赛同步赛 J-张老师的游戏
传送门 题目描述 在空闲时间,张老师习惯性地和菜哭武玩起了取石子游戏,这次的游戏规则有些不同,在他们面前有n堆石子,其中,第i堆石子的个数为a[i],现在制定规则如下: 从张老师开始, ...
- CTF 湖湘杯 2018 WriteUp (部分)
湖湘杯 2018 WriteUp (部分),欢迎转载,转载请注明出处! 1. CodeCheck(WEB) 测试admin ‘ or ‘1’=’1’# ,php报错.点击登录框下面的滚动通知,URL ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会部分题解
题目链接 2018 ACM 国际大学生程序设计竞赛上海大都会 下午午休起床被同学叫去打比赛233 然后已经过了2.5h了 先挑过得多的做了 .... A题 rand x*n 次点,每次judge一个点 ...
随机推荐
- python turtle画花
turtle是一个功能强调大的绘图的库,可以用来绘制各种所需要的图案,但是在使用时需要计算好角度等一系列的问题. 代码(源自<Python语言程序设计>)如下: 运行结果:
- 打印出三位数的水仙花数Python
水仙花数计算 ...
- SQL Server返回DATETIME类型,年、月、日、时、分、秒、毫秒
SQL Server返回DATETIME类型的年.月.日,有两种方法,如下所示: DECLARE @now DATETIME=GETDATE() --第一种方法 SELECT @now,YEAR(@n ...
- ios、安卓前端兼容性
1.日期兼容性 解决方法(请看我上一篇文章)安卓.ios时间转换成时间戳的形式 2.input框聚焦,ios出现outline或者阴影,安卓显示正常 解决方法 input:focus{outline: ...
- Python 之 计算psnr和ssim值
基于python版的PSNR和ssim值计算 总所周知,图像质量评价的常用指标有PSNR和SSIM等,本博文是基于python版的图像numpy的float64格式和uint8格式计算两种指标值(附代 ...
- 史上最全的整合第三方登录的工具JustAuth
JustAuth,如你所见,它仅仅是一个第三方授权登录的工具类库,它可以让我们脱离繁琐的第三方登录SDK,让登录变得So easy! 参考图例 授权gitee 授权github 授权weibo 授权钉 ...
- 转摘jemeter学习-连接数据库之jdbc请求
JMETER连接数据库 mysql下载地址:https://dev.mysql.com/downloads/connector/j/ mysql连接器根据语言选择/J,用的是Mac,选择下载.tar. ...
- vagrant 无法挂载共享目录
Vagrant was unable to mount VirtualBox shared folders. This is usually because the filesystem " ...
- Hive安装部署与配置
Hive安装部署与配置 1.1 Hive安装地址 1)Hive官网地址: http://hive.apache.org/ 2)文档查看地址: https://cwiki.apache.org/conf ...
- nginx与php分离搭建
nginx与php分离搭建 nginx配置 server { listen 80; 定义端口 server_name www.a.org; 定义域名 location / ...