首页
关于
友情链接
推荐
百度一下
腾讯视频
百度一下
腾讯视频
Search
1
【笔记】用Javascript实现椭圆曲线加密算法
28 阅读
2
USTC Hackergame 2022 个人题解
20 阅读
3
欢迎使用 Typecho
18 阅读
4
【折腾记录】香橙派在Docker环境下部署Nextcloud
18 阅读
5
【学习笔记】FourierTransform-关于二维DCT变换可以被表示为矩阵相乘这档事
14 阅读
默认分类
登录
Search
标签搜索
Note
CPP
CTF
C
JavaScript
Math
Bilibili
Python
Docker
php
RSA
ECC
Crypto
Blog
Bash
FPGA
GAMES
Homework
HackerGame
依言 - Eyan
累计撰写
35
篇文章
累计收到
4
条评论
首页
栏目
默认分类
页面
关于
友情链接
推荐
百度一下
腾讯视频
百度一下
腾讯视频
搜索到
35
篇与
的结果
2019-11-20
【CTF】CTF中常用的脚本(转载+自写)
Script:栅栏密码:#!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @Time : 2018/12/23 09:55:19 @Author : HeliantHuS @Version : 1.0 @Contact : 1984441370@qq.com ''' string = input("输入:") frequency = [] # 获得栅栏的栏数 result_len = len(string) # 栅栏密码的总长度 25 for i in range(2, result_len): # 最小栅栏长度为2 逐个测试2,3,4.... if(result_len % i == 0): # 当栅栏密码的总长度 模 i 余数为0 则这个i就是栅栏密码的长度 frequency.append(i) for numberOfColumn in frequency: # 循环可能分的栏数 RESULT = [] # 保存各栏数的结果 for i in range(numberOfColumn): # i : 开始取值的位置 for j in range(i, result_len, numberOfColumn): # 开始取值, 隔栏数取一个值, 起始位置是i RESULT.append(string[j]) print("".join(RESULT)) 凯撒密码:#!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @Time : 2018/12/23 09:56:53 @Author : HeliantHuS @Version : 1.0 @Contact : 1984441370@qq.com ''' import string inputStr = input("输入:").lower() caseS1 = string.ascii_lowercase * 2 # caseS1 = string.ascii_uppercase * 2 for j in range(26): result_list = [] for i, num in zip(inputStr, range(len(inputStr))): status = caseS1.find(i) if status != -1: result_list.append(caseS1[status + j]) else: result_list.append(inputStr[num]) print("".join(result_list), "向右偏移了{}位".format(j)) xor异或:#!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @Time : 2018/12/20 14:17:59 @Author : HeliantHuS @Version : 1.0 @Contact : 1984441370@qq.com 可以进行字符串的异或运算 可xor加密也可以解密 思路就是先将要解码的字符串转换为ascii码, 然后穷举一个数字 i , 将这个数字i与字符串的ascii码进行异或运算,将结果再转换为字符串 ''' import base64 s1 = list(b'') for i in range(200): # 进行穷举的数字可高可低 result = "" for j in range(len(s1)): result += chr(s1[j] ^ i) print(result) ROT13:#!/usr/bin/env python # -*- coding: utf-8 -*- ''' @Author : HeliantHuS @Time : 2018/12/17 8:26 @Version : 1.0 @Contact : 1984441370@qq.com ''' import string s1 = "" rot13_1 = string.ascii_lowercase[:13] rot13_2 = string.ascii_lowercase[13:] result = [] for i in s1: find_1 = rot13_1.find(i.lower()) if find_1 != -1: if i.isupper(): result.append(rot13_2[find_1].upper()) continue result.append(rot13_2[find_1]) find_2 = rot13_2.find(i.lower()) if find_2 != -1: if i.isupper(): result.append(rot13_1[find_2].upper()) continue result.append(rot13_1[find_2]) if find_1 == -1 and find_2 == -1: result.append(i) print("". join(result)) GCD:#!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @Time : 2018/12/22 11:10:50 @Author : HeliantHuS @Version : 1.0 @Contact : 1984441370@qq.com ''' def gcd(a, b): if b == 0: return a else: return gcd(b, a % b) AuthorHeliantHuS
2019年11月20日
3 阅读
0 评论
0 点赞
2019-11-19
【转载】C/C++遍历目录下的所有文件(Windows/Linux篇,超详细)
本文可转载,转载请注明出处:http://www.cnblogs.com/collectionne/p/6815924.html。前面的一篇文章我们讲了用Windows API遍历一个目录下的所有文件,这次我们讲用一种Windows/Linux通用的方法遍历一个目录下的所有文件。Windows/Linux的IDE都会提供一个头文件——<io.h>。看名字,似乎是关于I/O的,但是实际上它还提供了类似于WIN32_FIND_DATA、FindFirstFile()、FindNextFile()和FindClose()的查找文件的功能。_finddata_t结构_finddata_t结构用来记录查找到的文件的信息。实际上有_finddata32_t、_finddata32i64_t、_finddata64i32_t、_finddata64_t、_wfinddata32_t、_wfinddata32i64_t、_wfinddata64i32_t、_wfinddata64_t八个结构,但都只是在32位/64位整数和字符类型上有所区别,但整体上相同。大致定义如下(MSDN):struct _finddata_t { unsigned attrib; size_t time_create; size_t time_access; size_t time_write; _fsize_t size; char name[_MAX_PATH]; };对于不同的_finddata_t结构,time_create、time_access和time_write的类型为_time32_t或_time64_t,size的类型为_fsize_t或__int64,name为char[_MAX_PATH]或wchar_t[_MAX_PATH]。attribunsigned类型,文件属性。time_create_time32_t/_time64_t类型,文件创建时间(FAT文件系统为-1)。以UTC格式存储,如果需要转换成当地时间,使用localtime_s()。time_access_time32_t/_time64_t类型,文件最后一次被访问的时间(FAT文件系统为-1)。以UTC格式存储,如果需要转换成当地时间,使用localtime_s()。time_write_time32_t/_time64_t类型,文件最后一次被写入的时间。以UTC格式存储,如果需要转换成当地时间,使用localtime_s()。size_fsize_t/__int64类型,文件的长度(以字节为单位)。namechar[_MAX_PATH]/wchar_t[_MAX_PATH]类型,文件/目录名,不包含路径。对于不支持文件创建时间、文件上一次访问时间的文件系统,time_create和time_access为-1。_MAX_PATH在stdlib.h中被定义为260。一般_finddata_t被定义为_finddata32_t/_finddata64i32_t,_wfinddata_t被定义为_wfinddata32_t/_wfinddata64i32_t。为方便,下文中将_finddata_t和_wfinddata_t统称为_finddata_t。文件属性常量一个文件/目录可以有多种属性,每种属性可以是下面列出的属性之一。_A_ARCH档案。文件被BACKUP指令改变或清除时被设置。值:0x20。_A_HIDDEN隐藏。使用DIR指令一般看不到,除非使用/AH选项。值:0x02。_A_NORMAL普通。文件没有更多属性被设置,可以没有限制地被读或写。值:0x00。_A_RDONLY只读。不能以“写”为目的打开该文件,并且不能创建同名的文件。值:0x01。_A_SUBDIR子目录。值:0x10。_A_SYSTEM系统文件。使用DIR指令一般看不见,除非使用/A或/A:S选项。值:0x04。要检查x是否含有某个属性a,可以用x & a进行检查。指定多个属性可以使用按位or运算符,例如_A_SYSTEM | _A_RDONLY | _A_HIDDEN。通配符(wildcards)遍历文件目录时需要使用通配符,详见我的另一篇文章。_findfirst()/_findnext()/_findclose()函数_findfirst()函数intptr_t _findfirst( const char * filespec, struct _finddata_t *fileinfo );实际上_findfirst()有10个版本,这里只列出一个。filespecconst char /const wchar_t 类型,目标文件说明(可包含通配符)。fileinfo_finddata_t *类型,函数将会填入文件/目录信息。返回值如果成功,返回一个唯一的搜索句柄标识一个或一组和filespec说明匹配的文件,可以用于接下来的_findnext()和_findclose()函数。否则_findfirst()返回-1。注意,intptr_t并不是指针类型,只是int或__int64的typedef。_findnext()函数int _findnext( intptr_t handle, struct _finddata_t *fileinfo );handleintptr_t类型,搜索句柄。fileinfo_finddata_t *类型,函数将会填入文件/目录信息。返回值如果成功,返回0,否则返回-1。如果没有更多能够找到的文件了,也会导致失败。_findclose()函数int _findclose( intptr_t handle );关闭搜索句柄并释放相应的资源。handle搜索句柄。返回值成功返回0,失败返回-1。程序代码[toc]1. 遍历目录下的所有文件#include <iostream> #include <cstring> // for strcat() #include <io.h> using namespace std; void listFiles(const char * dir); int main() { char dir[200]; cout << "Enter a directory (ends with \'\\\'): "; cin.getline(dir, 200); strcat(dir, "*.*"); // 在要遍历的目录后加上通配符 listFiles(dir); return 0; } void listFiles(const char * dir) { intptr_t handle; _finddata_t findData; handle = _findfirst(dir, &findData); // 查找目录中的第一个文件 if (handle == -1) { cout << "Failed to find first file!\n"; return; } do { if (findData.attrib & _A_SUBDIR && strcmp(findData.name, ".") == 0 && strcmp(findData.name, "..") == 0 ) // 是否是子目录并且不为"."或".." cout << findData.name << "\t<dir>\n"; else cout << findData.name << "\t" << findData.size << endl; } while (_findnext(handle, &findData) == 0); // 查找目录中的下一个文件 cout << "Done!\n"; _findclose(handle); // 关闭搜索句柄 }程序遍历目录下的所有文件/目录,如果是文件则输出文件大小。注意_findnext()函数成功返回0,因此要加上==0或!=-1进行判断,不能省略。此外还有一个值得注意的地方:if (findData.attrib & _A_SUBDIR || strcmp(findData.name, ".") || strcmp(findData.name, "..") )使用_findfirst()、_findnext()进行搜索时,可能会得到"."和".."两个文件夹名。这两个值可以忽略。[toc]2. 遍历目录中的所有文件注意是“目录中”而不是“目录下”,这个程序将会遍历一个目录里包含的所有文件。#include <iostream> #include <cstring> // for strcpy(), strcat() #include <io.h> using namespace std; void listFiles(const char * dir); int main() { char dir[200]; cout << "Enter a directory: "; cin.getline(dir, 200); listFiles(dir); return 0; } void listFiles(const char * dir) { char dirNew[200]; strcpy(dirNew, dir); strcat(dirNew, "\\*.*"); // 在目录后面加上"\\*.*"进行第一次搜索 intptr_t handle; _finddata_t findData; handle = _findfirst(dirNew, &findData); if (handle == -1) // 检查是否成功 return; do { if (findData.attrib & _A_SUBDIR) { if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0) continue; cout << findData.name << "\t<dir>\n"; // 在目录后面加上"\\"和搜索到的目录名进行下一次搜索 strcpy(dirNew, dir); strcat(dirNew, "\\"); strcat(dirNew, findData.name); listFiles(dirNew); } else cout << findData.name << "\t" << findData.size << " bytes.\n"; } while (_findnext(handle, &findData) == 0); _findclose(handle); // 关闭搜索句柄 }
2019年11月19日
3 阅读
0 评论
0 点赞
2019-11-16
Codeforces Round #585 (Div. 2) (codeforces 1215)
emmm,于是我又来水文章了((传送门)A. Yellow Cards (CF1215A)题意给定黄牌的数量,判断被踢下场人数的最大值和最小值题解算是个贪心?算最小值时就先把每个人最大的数量减一减去,还剩几个黄牌就最少走几个人。算最大时先把需要黄牌少的人先踢光再去看能踢几个需要黄牌多的队的人。。。代码#include <bits/stdc++.h> using namespace std; int main(){ int a1,a2,k1,k2,n; while (scanf("%d%d%d%d%d",&a1,&a2,&k1,&k2,&n) != EOF){ //min int nu = a1*(k1-1)+a2*(k2-1); int cardleft = n-nu; if(cardleft<0)cardleft=0; //max int out1,out2; if(k1>k2){ out2 = n / k2; n -= out2 * k2; if(out2 > a2){ n += (out2-a2)*k2; out2 = a2; } out1 = n / k1; } else{ out1 = n / k1; n -= out1 * k1; if(out1 > a1){ n += (out1-a1)*k1; out1 = a1; } out2 = n / k2; } //out printf("%d %d\n",cardleft,out1+out2); } return 0; }(感觉还可以再优化下的,懒得改了,之后再说吧emmB.The Number of Products (CF1215B)题意给定一个不为零的数字序列,求连续的相乘为正数和复数的子序列各有多少给。题解(刚开始写的暴力,结果超时了QAQ。之后看落叶dalao后写的)差不多就是遍历一遍数组,记下以当前元素为结尾的子序列相乘得正数和负数的各有多少,再读一个数,如果是正数就在得正数的子序列数量加一,如果是负数就在得正数的子序列数量加一再交换一下得正负的子序列的数量(自己在草稿纸上瞎算总结出来的)再之后在总的得正负的子序列数量加上本轮的以最后一个元素结尾相乘得正负的子序列的数量就行了(我都不知道自己在说些什么)。。还是看代码吧。。代码#include <bits/stdc++.h> #define il inline #define ll long long #define Max 200005 #define int ll using namespace std; int num[Max],f[Max][2]; //0 for positive, 1 for negative. il int read() { char c=getchar(); int x=0,f=1; while(c>'9'||c<'0') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } signed main(){ int n = read(); int last_neg_seq = 0, last_pos_seq = 0; int neg = 0, pos = 0; for(int i = 0;i < n;i++){ int tmp = (int)(read()<0); last_pos_seq++; if(tmp){ int tmp2 = last_pos_seq; last_pos_seq = last_neg_seq; last_neg_seq = tmp2; } neg += last_neg_seq; pos += last_pos_seq; //debug; //printf("%d %d %d %d\n",last_neg_seq,last_pos_seq,neg,pos); } //printf("%d %d",neg,pos); cout<<neg<<" "<<pos; return 0; }C.Swap Letters (CF1215C)题意给定两个由a和b组成的字符串,每次可以调换一个上面的和一个下面的元素。求使两个字符串相同需要的最少调换次数和调换步骤。题解首先统计下a的数量,如果a为奇数个,那就不可能使上下相同,直接输出-1.读入数组时统计下上下不同的位置和上面的元素是a还是b。如果a和b都是偶数个就可以简单的直接一次拿两个a或两个b的index就先,如果a和b都是奇数个,第一次就拿一个a和一个b,先输出两遍a的index,接下来就当作第一种情况就行了233.代码#include <bits/stdc++.h> using namespace std; char str[2][200100] = { 0 }; int sa[200100],sb[200100]; int pa=0,pb=0,pa2=0,pb2=0; int ans = 0; int main(){ int n; cin>>n; int num = 0; for(int i = 0;i < 2;i++){ scanf("%s",str[i]); } for(int i = 0;i < n;i++){ if(str[0][i] != str[1][i]){ num++; str[0][i]=='a'?sa[pa++]=i:sb[pb++]=i; } } //debug; //printf("%s\n%s\n",str[0],str[1]); if(num%2){printf("%d\n",-1);return 0; } else{ if(pa%2){ printf("%d\n",num/2+1); printf("%d %d\n",sa[pa2]+1,sa[pa2]+1); printf("%d %d\n",sa[pa2++]+1,sb[pb2++]+1); } else printf("%d\n",num/2); while(pa2<pa){ printf("%d %d\n",sa[pa2++]+1,sa[pa2++]+1); } while(pb2<pb){ printf("%d %d\n",sb[pb2++]+1,sb[pb2++]+1); } } }D. Ticket Game (CF1215D)题意有长度为n的串,内容为0-9数字或'?'。Mono先手,填数。Mono希望前n/2个数和!=后n/2个数和。Bicarp希望相等。问谁能赢。题解自己不会解QAQ,这里就转载下某大佬的解吧emm博弈论 Codeforces1215D Ticket Game分析:先是高级做法设L为左半边减右半部最小情况(左边污染部分全赋为0,右边全赋为9),R为左半边减右半边最大情况若(L+R)/2=0,则B赢,否则就是A赢。证明:若没有污染部分,则显然(L+R)/2=0,就是B赢,否则就是A赢。若有污染部分,第一个玩家开始执行操作后,每次操作都会使L的值变为L~L+9之间(左边污染部分设为0或右边设为9不变,左边设为9或右边设为0变成L+9)。注:L变后会也会对应的改变R,总体的改变是每次操作使R-L减少9.如果(L+R)>0,第一个玩家肯定会选择继续增大L,将L变为L+9,之后的第二个玩家为了消除影响,会把R变为R-9,但这永远都只是消除影响,回到初始状态,赢不了,(L+R)<0时候的情况也一样。核心就是:第一个选手把局势破坏,而第二个选手只能填前一个的坑,永远无法改变局势,既然局势一开始赢不了,那就永远赢不了。大概就是左边的数减右边的数得到一个差值,Mono要尽力增大差值的绝对值,而Bicarp要把差值变成0.刚开始二者不断消耗左边和右边的?直到只有一边剩下?。如果这个时候差值==?的数量/29,就是Bicarp赢,否则就是Mono赢。当差值大于?/29时Mono可以每次出0,这样Bicarp最大只能出9,无法减去所有的差值,差值小于?/2*9时同理。(我怎么又不懂自己在说什么了)代码#include <bits/stdc++.h> using namespace std; #define MWIN printf("Monocarp") #define BWIN printf("Bicarp") int n; char str[200100]; int suml=0,sumr=0; int lq=0,rq=0; inline int abs(int x){ return (x>0)?x:-x; } int main(){ cin>>n; scanf("%s",str); for(int i = 0;i < n/2;i++){ if(str[i]>='0'&&str[i]<='9')suml+=str[i]-'0'; else lq++; } for(int i = n/2;i < n;i++){ if(str[i]>='0'&&str[i]<='9')sumr+=str[i]-'0'; else rq++; } //debug //printf("%d %d %d %d\n",suml,sumr,lq,rq); if(suml==sumr){ lq==rq ? BWIN : MWIN ; } else{ (suml-sumr==(rq-lq)/2*9) ? BWIN : MWIN ; } return 0; }(同样有的地方还可以优化优化,但我懒得写了emm)E. MarblesF. Radio Stations两道不会的题,大佬的题解也看不懂,以后再说吧QWQ
2019年11月16日
7 阅读
0 评论
0 点赞
2019-11-06
【作业】为什么不试试神奇的Final Mission 呢?
前言-关于为什么会有这篇文章那当然是因为我想要水篇文章啦 咳咳,还不是因为某个Final Mission,写完了当然来水一篇文章咯(关于前端当写到这里的时候,忽然想起来之前做的某道web题的前端还行,于是就偷过来咯(x)<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Rabbit House 成员管理系统</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="content container pt-5"> <h1>Rabbit House 成员管理系统</h1> <form method="post" action="."> <div class="form-group"> <label> 用户名:<input type="text" class="form-control" name="username"> </label> </div> <div class="form-group"> <label> 密码:<input type="password" class="form-control" name="password"> </label> </div> <button type="submit" class="btn btn-primary">登录</button> </form> </div> </body> </html>数据库部分考虑到这个项目的要求有登录,注销以及留言功能,所以需要用到数据库。我建立的数据表结构如下:首先建一个final_database来存放这个项目的数据。final_user 结构如下:username显然是用户的id,password用来保存用户的密码,按照需要也可以保存密码的md5,head_path保存用户的头像路径。msg_book 结构如下:username是用户id,post_time保存用户留言的时间,text是用户留言的内容,最后的post_time是偷个懒,用户留言时直接把头像路径保存,略去输出用户留言时再去查询头像。user_auth 结构如下:username是用户id,再用户登陆时会随机生成一串数字作为验证,随机数保存于userauth,登陆时间保存于authtime。项目包含文件由于项目各个模块基本都要用到cookie,mysql查询等功能,为了提高代码的复用率,所以这些代码写到一个文件,各个部分再包含这个文件。常量定义//Contest definations. define("MYSQL_HOST", "**.**.**.**"); define("MYSQL_USERNAME", "*********"); define("MYSQL_PASSWORD", "********"); define("MYSQL_DATABASE", "final_database"); //我的mysql怎么可能放在这呢( define("TABLE_USERLIST", "final_user"); define("TABLE_MSGBOOK", "msg_book"); define("TABLE_USERAUTH", "user_auth");cookie部分//Cookie control // 开启Session session_start(); $isLogin = false; if(isset($_COOKIE['username'])){ $isLogin=true; $user_name = $_COOKIE['username']; $head_path = $_COOKIE['headpath']; $user_auth = $_COOKIE['userauth']; }//把cookie的数据保存至变量方便后续使用 else{ $isLogin=false; }mysql部分//MySql Control $link = mysqli_connect(MYSQL_HOST, MYSQL_USERNAME, MYSQL_PASSWORD, MYSQL_DATABASE);MySql部分就相对比较简单了,后面需要查询的时候都是单独写的。。防XSS攻击模块由于用户的id和留言内容都是直接使用用户提交的字符串,就存在xss攻击的风险,所以要对用户提交的内容进行过滤。function anti_xss($text){ $text_anti_xss = trim($text); //清理空格 $text_anti_xss = strip_tags($text_anti_xss); //过滤html标签 $text_anti_xss = htmlspecialchars($text_anti_xss); //将字符内容转化为html实体 $text_anti_xss = addslashes($text_anti_xss); //防止SQL注入 return $text_anti_xss; }用户登录验证模块在用户登录之后发表信息的时候验证用户身份的部分,,,emm算了不描述了(function auth_check($auth, $name, $link){ $sql = "SELECT * FROM `".TABLE_USERAUTH."` WHERE username = '$name'"; $res = mysqli_query($link, $sql); $arr = mysqli_fetch_assoc($res); if($arr){ if($arr['userauth']==$auth && $arr['authtime'] + 3600 > time()){ return 1; } else { return 0; } } else { return -1; } } function auth_insert($auth, $name, $link){ //Check that user authentication exists. $tmp = auth_check($auth, $name, $link); if($tmp >= 0){ $sql2 = "UPDATE `user_auth` SET `userauth` = '$auth', `authtime` = '".time()."' WHERE `user_auth`.`username` = '$name'"; mysqli_query($link, $sql2); } else if($tmp == -1){ $sql2 = "INSERT INTO `".TABLE_USERAUTH."` (`username`, `userauth`, `authtime`) VALUES ('$name', '$auth', '".time()."')"; mysqli_query($link, $sql2); } }具体讲解之后再补吧emm用户登录部分设计function user_login($username, $password, $link){ $sql = "SELECT * FROM `final_user` WHERE username = '$username'"; $res = mysqli_query($link, $sql); $arr = mysqli_fetch_assoc($res); $password_md5ed = md5($password); if($arr){ if($arr['password']==$password_md5ed){ $auth_tmp = rand(1000000,9999999); setcookie("username",$_POST["username"],time()+3600); setcookie("headpath",$arr["head_path"],time()+3600); setcookie("userauth",$auth_tmp,time()+3600); auth_insert($auth_tmp, $username, $link); echo"<script>alert('登录成功!');location.href = 'index.php';</script>"; }else{ echo"<script>alert('密码错误!');location.href = 'index.php';</script>"; } }else{ echo "<script>alert('".$username."');</script>"; echo"<script>alert('用户名不存在,请先注册!');location.href = 'index.php';</script>"; } }在收到用户的登录请求时,通过提交的用户名查询到密码的md5值,然后再将密码md5之后进行比较。登录成功后进行cookie的设置和用户auth信息的更新。用户注册部分设计function user_register($username, $password, $link){ $username_anti_xss = anti_xss($username); $sql = "SELECT * FROM `".TABLE_USERLIST."` WHERE username = '$username_anti_xss'"; $res = mysqli_query($link, $sql); $arr = mysqli_fetch_assoc($res); if($arr){ echo"<script>alert('用户名已存在!');location.href = 'index.php';</script>"; }else{ $password_md5ed = md5($password); $sql2 = "INSERT INTO `".TABLE_USERLIST."` (`username`, `password`, `head_path`) VALUES ('$username_anti_xss', '$password_md5ed', NULL)"; mysqli_query($link, $sql2); echo"<script>alert('注册成功!');location.href = 'index.php';</script>"; } }和用户登录部分大体一致用户登出部分设计function user_logout(){ setcookie("username",$user_name,time()-3600); setcookie("headpath",$head_path,time()-3600); setcookie("userauth",$user_auth,time()-3600); echo "<script>alert('注销成功!');location.href = 'index.php';</script>"; }在用户登出时删除所有cookie,还应该更新下用户的auth信息的,之后再补吧emmm发布留言部分设计function post_msg($text, $username, $headpath, $link){ $text_anti_xss = anti_xss($text); $sql2 = "INSERT INTO `".TABLE_MSGBOOK."` (`username`, `post_time`, `text`, `post_head`) VALUES ('$username', CURRENT_TIMESTAMP, '$text_anti_xss', '$headpath')"; mysqli_query($link, $sql2); echo"<script>alert('发送成功!');location.href = 'index.php';</script>"; }代码言简意赅,就这样吧(上传头像部分设计function post_img($img, $username, $link){ // 服务器中文件的存放目录 $tmp_dir=$img['tmp_name']; //用户上传的文件名(带后缀) $fileName=$img['name']; if($img['error']!=0){ echo '上传文件出现错误!请重试!'; return; }else if($img['size']>10240000){ echo "文件超过".$maxSize; return; }else if($img['size']<20480){ echo "上传文件出现错误!请重试!"; return; }else{ //创建目录 $fileDir='./upload/'; if(!is_dir($fileDir)){ mkdir($fileDir); } //文件名 $newFileName=date('YmdHis',time()).rand(100,999); //文件后缀 $FileExt=substr($fileName,strrpos($fileName,'.')); $FilePath=$newFileName.$FileExt; //生成缩略图 $img_info=getimagesize($tmp_dir); // var_dump($img_info); $width=$img_info[0]; //原图的宽 $height=$img_info[1]; //原图的高 $newWidth=$width*0.5; $newHeight=$height*0.5; //绘制画布 $thumb=imagecreatetruecolor($newWidth, $newHeight); //创建一个和原图一样的资源 $source=imagecreatefromjpeg($tmp_dir); //根据原图创建缩略图 imagecopyresized($thumb,$source,0,0,0,0,$newWidth,$newHeight,$width,$height); //保存缩略图 imagejpeg($thumb,'./upload/'.$newFileName.$FileExt,100); //移动文件到指定的目录 move_uploaded_file($tmp_dir,'./upload/'.$newFileName.'_temp'.$FileExt); unlink('./upload/'.$newFileName.'_temp'.$FileExt); $sql2 = "update final_user set `head_path`='$FilePath' WHERE username = '$username'"; mysqli_query($link, $sql2); setcookie("headpath",$FilePath,time()+3600); echo "<script>alert('上传成功!');location.href = 'index.php';</script>"; } }为了避免文件上传存在的风险,于是选择在用户上传图片后进行压缩,从而避免文件上传的风险。接下来就是各个部分的前端了首页部分 index.php<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Rabbit 留言本 ^ - ^</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="content container pt-5"> <h1>Rabbit 留言本 ^ - ^</h1> <p>本站提供注册,登录,留言板功能!</p> <?php include "include.php"; if ($isLogin) { // 若已经登录 //输出用户信息 echo "你好! ".$user_name.' ,欢迎来到个人中心!<br>'; echo "<img src=\"./upload/$head_path\" width=50 height=50> "; echo "<a class=\"btn btn-warning\" href='logout.php'>注销</a> "; echo "<a class=\"btn btn-warning\" href='upimg.html'>上传/修改头像</a>"; } else { // 若没有登录 echo "您还没有登录,请先登录!</a>"; } ?> <form method="post" action="login.php" <?php if ($isLogin)echo "hidden"?>> <div class="form-group"> <label> 用户名:<input type="text" class="form-control" name="username"> </label> </div> <div class="form-group"> <label> 密码:<input type="password" class="form-control" name="password"> </label> </div> <button type="submit" class="btn btn-primary">登录</button> <a class="btn btn-success" href="register.php">没有id?点击注册</a> </form> <div id="loged" <?php if (!$isLogin)echo "hidden"?>> <p>test233</p> <table border="1" width=80%> <tr> <td>Test</td> <td width=80%>test message</td> </tr> <?php //输出留言信息 $query='select * from msg_book'; $result=mysqli_query($link, $query); //echo '<br> <br>'; while ($data=mysqli_fetch_assoc($result)){ echo '<tr>'; echo '<td>'; echo "<img src=\"./upload/".$data[post_head]."\" width=50 height=50> <br> $data[username] <br> "; echo $data[post_time]; echo '</td>'; echo '<td>'.$data[text].'</td>'; //echo '</tr>\n' } ?> <tr> <td>Admin<br>2019-11-3 22:45</td> <td width=80%>Welcome!</td> </tr> <tr> <td colspan="2"> <form name="input" action="postmsg.php" method="post"> 回复内容: <input type="text" name="text"> <input type="submit" value="Submit"> </form> </td> </tr> </table> </div> <br> <p>本站仅供学习使用,请勿用于任何非法用途!<del>更不要日站!!!</del></p> </div> </body> </html>判断用户是否登录来对对部分内容进行隐藏,中间通过查询留言本按照表格输出数据。注册页面 register.php(注:后面html部分基本相同所以只写body部分了。。)<?php header('content-type:text/html;charset=utf-8'); include "include.php"; //检测用户是否登录 if ($isLogin) { echo"<script>alert('您已经登录请不要重复注册!');location.href = 'index.php';</script>"; } if(isset($_POST['username'])){ $name = $_POST["username"]; $pwd = $_POST["password"]; user_register($name, $pwd, $link); } ?>登录页面 login.php<?php header('content-type:text/html;charset=utf-8'); include "include.php"; //检测用户是否登录 if ($isLogin) { echo"<script>alert('您已经登录请不要重复登录!');location.href = 'index.php';</script>"; } //接受客户端的数据: $name = $_POST["username"]; $pwd = $_POST["password"]; user_login($name, $pwd, $link); ?>登出页面 louout.php<?php header('content-type:text/html;charset=utf-8'); include "include.php"; user_logout(); ?>发布留言页面 postmsg.php<?php header('content-type:text/html;charset=utf-8'); include "include.php"; //检测用户是否登录 if (!$isLogin) { echo"<script>alert('您还没有登录!');location.href = 'index.php';</script>"; exit(); } //检测认证信息 if(auth_check($user_auth, $user_name, $link)!=1){ echo"登陆信息出错,信息提交失败!"; exit(); } //接受客户端的数据: $text = $_POST["text"]; $name = $_COOKIE["username"]; $hdpath=$_COOKIE['headpath']; post_msg($text, $name, $hdpath, $link); ?>上传头像页面upimg.html<body> <p>建议上传jpg格式图片。</p> <form action="upImg.php" method="post" enctype="multipart/form-data"> <input type="file" name="userImg" > <input type="submit" value="上传"> </form>upimg.php<?php header('content-type:text/html;charset=utf-8'); date_default_timezone_set("PRC"); include "include.php"; $img=$_FILES['userImg']; post_img($img, $user_name, $link); ?>之后,是这个项目的一些参考:PHP上传用户头像及头像的缩略图PHP防XSS攻击b站之前学php的视频(的笔记)项目已上传至github,欢迎一起来玩鸭~https://github.com/panedioic/rabbit_msgbook
2019年11月06日
4 阅读
0 评论
0 点赞
2019-10-23
中国科学技术大学第六届信息安全大赛(HACKERGAME2019自我总结)
https://hack.lug.ustc.edu.cn/入了这个坑的十几天后第一次打比赛,没想到自己居然还能答6道题,趁着刚开始人不多居然还能有70左右的名次()就这样,写个总结。。。(10.23补充:原本前天就该搞好的文章结果拖到了现在,果然我已经懒癌晚期了。。。快结束的时候居然又多做了一道题,结束时总分900.看了其他题的wp,果然我的知识还是太匮乏了。。。)0x01 签到题题目描述:签到题就在这里~最简单的一道题了,只要把button的属性改一下点击就可以得到flag。甚至官方已经在题目中给出了flag(0x02 白与夜题目描述: 这是一个关于白猫,嗯不对,关于黑猫的故事。打开后发现是一个网页文档,有个图片,提示猫是黑的,然后下载下来不知道怎么的就稀里糊涂的看到flag了,等官方wp吧(0x03 信息安全 2077题目描述:2077 年很快到来了。此时正值祖国 128 周年华诞,中国科学技术大学也因其王牌专业信息安全,走出国门,成为了世界一流大学。作为向信息安全专业输送人才的重要渠道,第 64 届信息安全大赛也正在如火如荼地开展着。千里之行,始于足下。作为一名渴望进入信息安全专业的学生,你的第一个任务是拿到第 64 届信息安全大赛的签到题的 flag。我们已经为你找到了签到题的入口,你只需要把 flag.txt 的内容读出来就可以了。注:为了照顾到使用黑曜石浏览器的用户,第 64 届信息安全大赛的签到题决定沿袭之前 63 届信息安全大赛的惯例,仍然基于 HTTP 1.x。当然了,使用其他浏览器也是可以顺利完成任务的。进入入口后提示还没到时间刚开始以为要搞js什么的,后来一想直接改系统时间就行了,再然后发现win系统只能改到2076,害得我只好拿出kali去改时间,再访问网页,得到flag。(懒得截图了,之后补吧)0x04 宇宙终极问题题目描述:(直接上图)连接后要求输入三个数立方和等于42,直接百度即可。再往后就不会做了,等wp吧。。。0x05 网页读取器题目描述:今年,刚刚学会网络编程的小 T 花了一点时间,写了一个非常简单的网站:输入一个 URL,返回对应的内容。不过小 T 想对用户访问的站点进行一些限制,所以他决定自己来解析 URL,阻止不满足要求的请求。这样也顺便解决了 SSRF(Server-Side Request Forgery, 服务器端请求伪造)的问题。想象很美好,但小 T 真的彻底解决了问题吗?打开/下载题目打开之后输入url可以访问网页,但只能输入example.com。下载源代码:阅读判断的部分,发现@前的部分都不管,所以可以把目标网址放到@前面。http://web1/flag?@example.com访问即得到flag。?的作用是把后面的东西当成参数避免404.0x06 达拉崩吧大冒险题目描述:某一天,C 同学做了一个神奇的梦。在梦中,他来到了蒙达鲁克硫斯伯古比奇巴勒城……打开/下载题目非常有意思的一个题目,打开是一个冒险的游戏的界面。要求攻击大于恶龙的攻击。游戏过程中发现料理大市场处可以发送负值。于是ws.send(-922337203685477588),成功数据溢出,打龙得到flag0x07 Happy LUG从这里开始就不会了qaq,等着wp吧
2019年10月23日
8 阅读
0 评论
0 点赞
1
...
6
7