如何获取linux系统源代码下安卓源码的sha1值

Linux下校验下载文件的完整性(MD5,SHA1,PGP) - 推酷
Linux下校验下载文件的完整性(MD5,SHA1,PGP)
Linux下的学习开始总是艰难的,但有的时候,却发现Linux下远比Windows的操作来的实在的多——这下载文件的完整性就是其中一件,让本人觉着很爽的一件事情。在编译安装各种软件的时候,总要到各个网站上收集下软件源码包。正由于此,软件的入口就非常复杂,校验下载的文件是否被修改过就显得非常有必要了。而校验方法当前一般是MD5,SHA1,PGP三种。在Windows那个漫长的岁月里(沧桑有木有),一般只能接触到前两种——前提是你会去校验的话。
原理:对文件进行MD5 Hash,求出文件的MD5哈希值,通过下载后文件MD5哈希值和发布者提供的MD5哈希值是否一致来判断文件是否在发布者发布之后被篡改过。
说明:寿命老长的一个Hash算法,适用范围广,网站存储密码也经常使用。不同的文件产生的MD5哈希值是唯一的,但这点已经有办法通过对文件进行少量的修改,让文件的MD5后的哈希值保持一致。
使用:在CentOS下,要对文件进行MD5 Hash是很简单的,一个
命令即可:
# $是终端提示符,非输入.
# #号是注释
# 没有提示符的是输出
#直接输出MD5 Hash
$ md5sum your-downloaded-file-name
fd4a1bc10c926eb7ac823d8
your-downloaded-file-name
#将MD5 Hash值保存到md5-hash.txt文件中.
$ md5sum your-downloaded-file-name & md5-hash.txt
# 显示输出的md5-hast.txt内容
$ cat md5-hash.txt
fd4a1bc10c926eb7ac823d8
your-downloaded-file-name
# 通过md5-hash.txt来校验你下载的文件是否正确
$ md5sum -c md5-hash.txt
your-downloaded-file-name: OK
你是文件的发布者话,你可以通过md5sum把文件的哈希值发送给验证者,这样下载你文件的人就可以通过MD5哈希值来验证你的文件正确性。反过来,我们在网站上下载文件之后,同时可以获取发布者的MD5哈希值和本地生成的Hash值对比,如果一致,认为文件是正确的。
原理: 原理同MD5一样,都是通过对文件进行HASH求值,比对文件发布者发布的HASH值,通过是否相等判断文件是否被篡改
说明: SHA1 HASH求值方法可以说是MD5的一个升级版本(SHA1 20位,MD5 16位),在HASH求值方面,MD5退出的舞台将有SHA1占据。SHA家族有五个算法:SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512,后四种有时候称为SHA2
使用: CentOS有SHA1的命令:
# 说明同上
# 直接输出SHA1 Hash
$ sha1sum your-downloaded-file-name
12dc96cbd0c1a77227
your-downloaded-file-name
# 将SHA1 Hash值保存到文件中
$ sha1sum your-downloaded-file-name & sha1-hash.txt
# 显示文件内容
$ cat sha1-hash.txt
12dc96cbd0c1a77227
your-downloaded-file-name
#通过sha1-hash.txt来校验我们下载的文件your-downloaded-file-name
# 注意,文件必须要要通过txt文件中的路径知道哦
$ sha1sum -c sha1-hash.txt
your-downloaded-file-name: OK
&这个SHA1和MD5基本一致,需要补充说明下的是,在使用
也好,还是
也罢,校验文件的时候,务必要让系统能够根据文件中提供的路径找到文件,如果文件找不到,是没有办法进行校验的。
如果是做多个文件的Hash校验,可以通过一个文件保存多个文件的Hash值即可。
原理:使用非对称加密,程序生成唯一的密钥对(公钥和私钥:Public Key和Private Key/Secret Key)。操作方法如下:
发布者通过用生成的密钥对中的私钥对要发布的文件进行签名,得到签名文件(sign);
发布者将密钥对中的公钥发布到公钥服务器;
发布者将文件和用私钥生成的签名一起发布;
验证者下载发布者发布的文件和签名;
使用PGP的程序获取的发布者第二步发布的公钥;
使用公钥校验文件签名
说明:签名算法中,密钥的用处分别是:公钥用于加密信息和验证,私钥用于解密和签名。私钥掌握在信息发布方,公钥可以任意分发。信息发布方用密钥进行对信息进行签名,接收方在获取公钥后,可以用公钥对发布方发布的信息+签名进行验证。如果验证失败则认为信息被篡改。在网络中,我们经常碰到的HTTPS协议,使用了同样的机制。
使用:由于PGP是商业应用程序,在CentOS/Linux中,具有同类功能的是GPG(也就是:GnuPG),同样遵守OpenPGP数据加密标准(
),没有安装可以用
yum install gnupg
安装,命令是:
# 说明同上
# 由于过程相对复杂,并且在实际使用中,校验用的比较多,因此这里只介绍文件的校验过程。
# 在获得文件和签名时,我们先用gpg校验签名,此时文件必须存在
$ gpg --verify downloaded-file-sign.asc
&这里有多种情况,如果你只有签名,但生成签名的文件不存在时(系统没找到,一般应该放在同目录下面),返回的是:
gpg: 不含签名的数据
gpg: can't hash datafile: No data
当你有文件的时候,但还没有与签名对应的公钥时,gpg返回的信息类似下面:
gpg: 于 日 星期一 18时27分27秒 CST 创建的签名,使用 RSA,钥匙号 47ACDAFB
gpg: 无法检查签名:No public key
注意:上面的信息在不同的文件和操作系统上生成的信息是不同的。但在没有公钥的时候,你可以发现gpg提供了一个该签名对应的钥匙号:47ACDAFB,这个是我们需要找的公钥。
上面已经说过,发布者已经将公钥发布到公钥服务器中,供验证者下载,因此我们需要到公钥服务器中下载公钥,要下载公钥,钥匙号就很重要了。
可用的公钥服务器可以通过wikipedia 上的Key Server条目来查看常用的一些key服务器列表。这里使用hkp://pgp.mit.edu:
# 获取服务器上的public key
$ gpg --keyserver hkp://pgp.mit.edu --recv-keys 47ACDAFB
gpg: 下载密钥‘47ACDAFB’,从 hkp 服务器 pgp.mit.edu
gpg: 密钥 47ACDAFB:公钥“Stephan Mueller &Stephan.&”已导入
gpg: 没有找到任何绝对信任的密钥
gpg: 合计被处理的数量:1
--recv-keys要与--keyserver配合使用,导入密钥对的公钥之后,我们就能够使用这个公钥来验证我们的签名了。
再次运行我们之前的验证命令(gpg --verify& sign-file),就可以看到验证的结果了。
#这时候我们再次验证我们的签名,就能得到验证结果了
$ gpg --verify downloaded-file-sign.asc
gpg: 于 日 星期一 18时27分27秒 CST 创建的签名,使用 RSA,钥匙号 47ACDAFB
gpg: 完好的签名,来自于“Stephan Mueller &Stephan.&”
gpg: 警告:这把密钥未经受信任的签名认证!
没有证据表明这个签名属于它所声称的持有者。
主钥指纹: B0F4 2D33 73F8 F6F5 10D4
93 A1C0 52F8
&看到这个结果,至少确认一个结果:这个文件是没有被篡改过的。
一般我们到这步也就差不多了。
但注意消息里面有个警告,说明这个是未受信任的签名认证。因为这个公钥谁都可以发布上去的,如果你确实需要进一步认证,可以在签名认证之前,你能还要联系下真正的发布者,确认这个密钥的信息——指纹!这个是这个算法的一个弱点。
如果签名认证已经通过,你也就可以安心的在自己的系统内编译,安装它了。
关于PGP的更多信息,可以参考以下网站:
,HOWTOs中MiniHOWTO中有个zh的文档,是中文的
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致C语言获取文件的SHA1哈希值_Linux编程_Linux公社-Linux系统门户网站
你好,游客
C语言获取文件的SHA1哈希值
来源:Linux社区&
作者:testcs_dn
安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准 (Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。 SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。
将C语言梳理一下,分布在以下10个章节中:
Linux-C成长之路(一):Linux下C编程概要
Linux-C成长之路(二):基本数据类型
Linux-C成长之路(三):基本IO函数操作
Linux-C成长之路(四):运算符
Linux-C成长之路(五):控制流
Linux-C成长之路(六):函数要义
Linux-C成长之路(七):数组与指针
Linux-C成长之路(八):存储类,动态内存
Linux-C成长之路(九):复合数据类型
Linux-C成长之路(十):其他高级议题
C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码
------------------------------------------源码下载:------------------------------------------
免费下载地址在
用户名与密码都是
具体下载目录在 /2014年资料/6月/26日/C语言获取文件的SHA1哈希值
下载方法见
----------------------------------------------分割线----------------------------------------------
SHA1 C语言实现
#include &stdio.h&#include &stdlib.h&#include &string.h&#include &assert.h&#include &errno.h&
#undef BIG_ENDIAN_HOSTtypedef unsigned int u32;
/***************** Rotate a 32 bit integer by n bytes*/#if defined(__GNUC__) && defined(__i386__)static inline u32&rol( u32 x, int n){&__asm__("roll %%cl,%0"& :"=r" (x)& :"0" (x),"c" (n));&}#else#define rol(x,n) ( ((x) && (n)) | ((x) && (32-(n))) )#endif
typedef struct {&u32& h0,h1,h2,h3,h4;&u32&&unsigned char buf[64];&int&} SHA1_CONTEXT;
void&sha1_init( SHA1_CONTEXT *hd ){&hd-&h0 = 0x;&hd-&h1 = 0xefcdab89;&hd-&h2 = 0x98&hd-&h3 = 0x;&hd-&h4 = 0xc3d2e1f0;&hd-&nblocks = 0;&hd-&count = 0;}
/***************** Transform the message X which consists of 16 32-bit-words*/static void&transform( SHA1_CONTEXT *hd, unsigned char *data ){&u32 a,b,c,d,e,&u32 x[16];
&/* get values from the chaining vars */&a = hd-&h0;&b = hd-&h1;&c = hd-&h2;&d = hd-&h3;&e = hd-&h4;
#ifdef BIG_ENDIAN_HOST&memcpy( x, data, 64 );#else&{&& unsigned char *p2;& for(i=0, p2=(unsigned char*)x; i & 16; i++, p2 += 4 ) & {& &p2[3] = *data++;& &p2[2] = *data++;& &p2[1] = *data++;& &p2[0] = *data++;& }&}#endif
#define K1& 0x5A827999L#define K2& 0x6ED9EBA1L#define K3& 0x8F1BBCDCL#define K4& 0xCA62C1D6L#define F1(x,y,z)& ( z ^ ( x & ( y ^ z ) ) )#define F2(x,y,z)& ( x ^ y ^ z )#define F3(x,y,z)& ( ( x & y ) | ( z & ( x | y ) ) )#define F4(x,y,z)& ( x ^ y ^ z )
#define M(i) ( tm =& x[i&0x0f] ^ x[(i-14)&0x0f] \&^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \&, (x[i&0x0f] = rol(tm,1)) )
#define R(a,b,c,d,e,f,k,m)& do { e += rol( a, 5 )& & \&+ f( b, c, d )& \&+ k& & & \&+& & & \&b = rol( b, 30 );& & \&} while(0)&R( a, b, c, d, e, F1, K1, x[ 0] );&R( e, a, b, c, d, F1, K1, x[ 1] );&R( d, e, a, b, c, F1, K1, x[ 2] );&R( c, d, e, a, b, F1, K1, x[ 3] );&R( b, c, d, e, a, F1, K1, x[ 4] );&R( a, b, c, d, e, F1, K1, x[ 5] );&R( e, a, b, c, d, F1, K1, x[ 6] );&R( d, e, a, b, c, F1, K1, x[ 7] );&R( c, d, e, a, b, F1, K1, x[ 8] );&R( b, c, d, e, a, F1, K1, x[ 9] );&R( a, b, c, d, e, F1, K1, x[10] );&R( e, a, b, c, d, F1, K1, x[11] );&R( d, e, a, b, c, F1, K1, x[12] );&R( c, d, e, a, b, F1, K1, x[13] );&R( b, c, d, e, a, F1, K1, x[14] );&R( a, b, c, d, e, F1, K1, x[15] );&R( e, a, b, c, d, F1, K1, M(16) );&R( d, e, a, b, c, F1, K1, M(17) );&R( c, d, e, a, b, F1, K1, M(18) );&R( b, c, d, e, a, F1, K1, M(19) );&R( a, b, c, d, e, F2, K2, M(20) );&R( e, a, b, c, d, F2, K2, M(21) );&R( d, e, a, b, c, F2, K2, M(22) );&R( c, d, e, a, b, F2, K2, M(23) );&R( b, c, d, e, a, F2, K2, M(24) );&R( a, b, c, d, e, F2, K2, M(25) );&R( e, a, b, c, d, F2, K2, M(26) );&R( d, e, a, b, c, F2, K2, M(27) );&R( c, d, e, a, b, F2, K2, M(28) );&R( b, c, d, e, a, F2, K2, M(29) );&R( a, b, c, d, e, F2, K2, M(30) );&R( e, a, b, c, d, F2, K2, M(31) );&R( d, e, a, b, c, F2, K2, M(32) );&R( c, d, e, a, b, F2, K2, M(33) );&R( b, c, d, e, a, F2, K2, M(34) );&R( a, b, c, d, e, F2, K2, M(35) );&R( e, a, b, c, d, F2, K2, M(36) );&R( d, e, a, b, c, F2, K2, M(37) );&R( c, d, e, a, b, F2, K2, M(38) );&R( b, c, d, e, a, F2, K2, M(39) );&R( a, b, c, d, e, F3, K3, M(40) );&R( e, a, b, c, d, F3, K3, M(41) );&R( d, e, a, b, c, F3, K3, M(42) );&R( c, d, e, a, b, F3, K3, M(43) );&R( b, c, d, e, a, F3, K3, M(44) );&R( a, b, c, d, e, F3, K3, M(45) );&R( e, a, b, c, d, F3, K3, M(46) );&R( d, e, a, b, c, F3, K3, M(47) );&R( c, d, e, a, b, F3, K3, M(48) );&R( b, c, d, e, a, F3, K3, M(49) );&R( a, b, c, d, e, F3, K3, M(50) );&R( e, a, b, c, d, F3, K3, M(51) );&R( d, e, a, b, c, F3, K3, M(52) );&R( c, d, e, a, b, F3, K3, M(53) );&R( b, c, d, e, a, F3, K3, M(54) );&R( a, b, c, d, e, F3, K3, M(55) );&R( e, a, b, c, d, F3, K3, M(56) );&R( d, e, a, b, c, F3, K3, M(57) );&R( c, d, e, a, b, F3, K3, M(58) );&R( b, c, d, e, a, F3, K3, M(59) );&R( a, b, c, d, e, F4, K4, M(60) );&R( e, a, b, c, d, F4, K4, M(61) );&R( d, e, a, b, c, F4, K4, M(62) );&R( c, d, e, a, b, F4, K4, M(63) );&R( b, c, d, e, a, F4, K4, M(64) );&R( a, b, c, d, e, F4, K4, M(65) );&R( e, a, b, c, d, F4, K4, M(66) );&R( d, e, a, b, c, F4, K4, M(67) );&R( c, d, e, a, b, F4, K4, M(68) );&R( b, c, d, e, a, F4, K4, M(69) );&R( a, b, c, d, e, F4, K4, M(70) );&R( e, a, b, c, d, F4, K4, M(71) );&R( d, e, a, b, c, F4, K4, M(72) );&R( c, d, e, a, b, F4, K4, M(73) );&R( b, c, d, e, a, F4, K4, M(74) );&R( a, b, c, d, e, F4, K4, M(75) );&R( e, a, b, c, d, F4, K4, M(76) );&R( d, e, a, b, c, F4, K4, M(77) );&R( c, d, e, a, b, F4, K4, M(78) );&R( b, c, d, e, a, F4, K4, M(79) );
&/* Update chaining vars */&hd-&h0 +=&hd-&h1 +=&hd-&h2 +=&hd-&h3 +=&hd-&h4 +=}
/* Update the message digest with the contents* of INBUF with length INLEN.*/static void&sha1_write( SHA1_CONTEXT *hd, unsigned char *inbuf, size_t inlen){&if( hd-&count == 64 ) { /* flush the buffer */& transform( hd, hd-&buf );& hd-&count = 0;& hd-&nblocks++;&}&if( !inbuf )&&if( hd-&count ) {& for( ; inlen && hd-&count & 64; inlen-- )& &hd-&buf[hd-&count++] = *inbuf++;& sha1_write( hd, NULL, 0 );& if( !inlen )& &&}
&while( inlen &= 64 ) {& transform( hd, inbuf );& hd-&count = 0;& hd-&nblocks++;& inlen -= 64;& inbuf += 64;&}&for( ; inlen && hd-&count & 64; inlen-- )& hd-&buf[hd-&count++] = *inbuf++;}
/* The routine final terminates the computation and* returns the digest.* The handle is prepared for a new cycle, but adding bytes to the* handle will the destroy the returned buffer.* Returns: 20 bytes representing the digest.*/
static void&sha1_final(SHA1_CONTEXT *hd){&u32 t, msb,&unsigned char *p;
&sha1_write(hd, NULL, 0); /* flush */;
&t = hd-&&/* multiply by 64 to make a byte count */&lsb = t && 6;&msb = t && 26;&/* add the count */&t =&if( (lsb += hd-&count) & t )& msb++;&/* multiply by 8 to make a bit count */&t =&lsb &&= 3;&msb &&= 3;&msb |= t && 29;
&if( hd-&count & 56 ) { /* enough room */& hd-&buf[hd-&count++] = 0x80; /* pad */& while( hd-&count & 56 )& &hd-&buf[hd-&count++] = 0;& /* pad */&}&else { /* need one extra block */& hd-&buf[hd-&count++] = 0x80; /* pad character */& while( hd-&count & 64 )& &hd-&buf[hd-&count++] = 0;& sha1_write(hd, NULL, 0);& /* flush */;& memset(hd-&buf, 0, 56 ); /* fill next block with zeroes */&}&/* append the 64 bit count */&hd-&buf[56] = msb && 24;&hd-&buf[57] = msb && 16;&hd-&buf[58] = msb &&& 8;&hd-&buf[59] = msb& & ;&hd-&buf[60] = lsb && 24;&hd-&buf[61] = lsb && 16;&hd-&buf[62] = lsb &&& 8;&hd-&buf[63] = lsb& & ;&transform( hd, hd-&buf );
&p = hd-&#ifdef BIG_ENDIAN_HOST#define X(a) do { *(u32*)p = hd-&h## p += 4; } while(0)#else /* little endian */#define X(a) do { *p++ = hd-&h##a && 24; *p++ = hd-&h##a && 16;& \&*p++ = hd-&h##a && 8; *p++ = hd-&h##a; } while(0)#endif&X(0);&X(1);&X(2);&X(3);&X(4);#undef X}
更多详情见请继续阅读下一页的精彩内容: &
相关资讯 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款Linux上计算MD5和SHA1-红联Linux系统门户
您的位置:
&& 查看内容 - - -
Linux上计算MD5和SHA1
pplicat发布于
&&字号: &&&&(网友评论&0&条)&
最近做JAVA 1.4.2的release,中美网络带宽很差,又要通过两边的防火墙,导致FTP上传的release包总是传不过去或者传得不完整,需要通过比较文件大小,以及哈希算法来进行完整性检查。两边的散列值一致,就算搞定了。
MD5 与 SHA1 是当前最常用的两种哈希算法。
在Linux下如何计算这两种哈希值呢,基本上所有的 Linux 发行版都内置了这两个命令,比如要校检的文件命为JAVA_142.tar:
1. 计算文件的 MD5 - md5sum
# md5sum JAVA_142.tar
bccc9c484e
JAVA_142.tar
2. 计算文件的 SHA1 - sha1sum
# sha1sum JAVA_142.tar
bb7d67fbedf35ec4a585ff8adc3dbda
JAVA_142.tar
发表评论,与各位同人交流。回复请点击下方的我要评论按钮(游客可回复),要发表贴子请点击
Linux教程下载?“”(请点击),Linux教程免费下载。
求助Linux问题?论坛有39版块,覆盖所有Linux技术层面。前往“”
 |  |  |  |  |  |  |  |  |  |  |  | 
&2015 红联 Powered by SupSiteAndroid获取网页源代码_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Android获取网页源代码
来源:Linux社区&
作者:feilong1105
1、首先在Manifest中加入Internet权限:
&!--&访问网络的权限&--&&&
&&uses-permission&android:name="android.permission.INTERNET"/&&&
2、Activity中得代码如下:
public&class&GetHtmlCodeActivity&extends&Activity&{&&
&&&&@Override&&
&&&&public&void&onCreate(Bundle&savedInstanceState)&{&&
&&&&&&&&super.onCreate(savedInstanceState);&&
&&&&&&&&setContentView(R.layout.main);&&
&&&&&&&&&&
&&&&&&&&TextView&textView&=&(TextView)this.findViewById(R.id.picture_textview);&&
&&&&&&&&try&{&&
&&&&&&&&&&&&textView.setText(getPictureData(""));&&
&&&&&&&&}&catch&(Exception&e)&{&&
&&&&&&&&&&&&Log.e("GetHtmlCodeActivity",&e.toString());&&
&&&&&&&&&&&&Toast.makeText(GetHtmlCodeActivity.this,&"网络连接失败",&1).show();&&
&&&&&&&&}&&
&&&&public&String&getPictureData(String&path)&throws&Exception{&&
&&&&&&&&&&
&&&&&&&&URL&url&=&new&URL("/");&&
&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&HttpURLConnection&conn&=&(HttpURLConnection)&url.openConnection();&&
&&&&&&&&&&
&&&&&&&&conn.setRequestMethod("GET");&&
&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&conn.setConnectTimeout(5&*&<FONT color=#c);&&
&&&&&&&&&&
&&&&&&&&InputStream&inStream&=&conn.getInputStream();&&
&&&&&&&&byte[]&data&=&readInputStream(inStream);&&
&&&&&&&&String&html&=&new&String(data);&&
&&&&&&&&return&&&
&&&&&&&&&&
&&&&public&byte[]&readInputStream(InputStream&inStream)&throws&Exception{&&
&&&&&&&&&&
&&&&&&&&ByteArrayOutputStream&outStream&=&new&ByteArrayOutputStream();&&
&&&&&&&&&&
&&&&&&&&byte[]&buffer&=&new&byte[<FONT color=#c];&&
&&&&&&&&int&len&=&0;&&
&&&&&&&&&&
&&&&&&&&while&((len&=&inStream.read(buffer))&!=&-1)&{&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&outStream.write(buffer,&0,&len);&&
&&&&&&&&}&&
&&&&&&&&inStream.close();&&
&&&&&&&&&&
&&&&&&&&return&outStream.toByteArray();&&
相关资讯 & & &
& (03月08日)
& (07/10/:11)
& (06/21/:10)
& (10/10/:25)
& (11/01/:39)
& (05/04/:37)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
匿名 发表于 连你mabi啊,连connect都没写,连个jb

我要回帖

更多关于 linux聊天系统源代码 的文章

 

随机推荐