DES加密算法实现
好久没写博客了,正好趁着实现网络工程与安全的DES算法的功夫,把代码发上来。
DES的介绍可见:DES加密
原理不赘述了。。实在太多,其实就是一个形式化算法,按部就班的实现就可以,只不过有些繁琐,我写了3个晚上 = =。
主要实现了利用DES算法对一个文本文档加密,然后再将其内容解密。
程序截图
明文和密钥
加密然后解密
密文和解密后文本
代码
//该程序实现了文本文档的DES加密和解密。 #include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std; //IP置换表
char IP[] = {
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,}; //IP^-1 置换表
char IP_1[] = {
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,}; //扩展置换表E
int E[] = {, , , , , ,
, , , , , ,
, ,,,,,
,,,,,,
,,,,,,
,,,,,,
,,,,,,
,,,,, }; //置换函数P
int P[] = {,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,}; //S盒
int S[][][] ={
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}, {{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}, {{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}, {{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}, {{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}, {{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}, {{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}, {{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}};
//置换选择1
int PC_1[] = {,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,}; //置换选择2
int PC_2[] = {,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,}; //对左移次数的规定
int LS[] = {,,,,,,,,,,,,,,,,}; //存放子密钥
unsigned __int64 K[]; //将含64个二进制字符的字符串转换为二进制形式存储在long long int中
unsigned __int64 str2bit(unsigned char s[])
{
unsigned __int64 bin = ;
int i;
for(i=;i<;i++){
bin = bin<< | (s[i]-''); //s[i]>>j & 1 表示取s[i]的第j位
}
return bin;
} //将含8位字符串转换为二进制形式存储在long long int中,例ABCDEFGH转换为64位二进制数
unsigned __int64 bstr2bit(unsigned char s[])
{
unsigned __int64 bin = ;
int i,j;
for(i=;i<;i++){
for(j=;j<;j++){
bin = bin | ( (unsigned __int64)((s[i]>>j)%) << (j+*(-i)) ); //将s[i]的第j位(低位开始)取出放到bin的对应位置
}
}
return bin;
} //将 unsigned __int64 形式的按十六进制串输出(64位有效的二进制数串)
void DisplayHex64(unsigned __int64 bin)
{
int i,t=;
for(i=;i>=;i--){
t = t<< | ((bin>>i) & );
if(i%==){
if(<=t && t<=)
printf("%d",t);
else if(<=t && t<=)
printf("%c",+t-);
t=;
}
if(i%==)
printf(" ");
}
printf("\n");
}
//将 unsigned __int64 形式的按十六进制串输出(48位有效的二进制数串)
void DisplayHex48(unsigned __int64 bin)
{
int i,t=;
for(i=;i>=;i--){
t = t<< | ((bin>>i) & );
if(i%==){
if(<=t && t<=)
printf("%d",t);
else if(<=t && t<=)
printf("%c",+t-);
t=;
}
if(i%==)
printf(" ");
}
printf("\n");
}
//将 unsigned __int64 形式的按十六进制串输出(32位有效的二进制数串)
void DisplayHex32(unsigned __int64 bin)
{
int i,t=;
for(i=;i>=;i--){
t = t<< | ((bin>>i) & );
if(i%==){
if(<=t && t<=)
printf("%d",t);
else if(<=t && t<=)
printf("%c",+t-);
t=;
}
if(i%==)
printf(" ");
}
printf("\n");
}
//将 unsigned __int64 形式的按十六进制串输出(28位有效的二进制数串)
void DisplayHex28(unsigned __int64 bin)
{
int i,t=;
for(i=;i>=;i--){
t = t<< | ((bin>>i) & );
if(i%==){
if(<=t && t<=)
printf("%d",t);
else if(<=t && t<=)
printf("%c",+t-);
t=;
}
if(i%==)
printf(" ");
}
printf("\n");
} //将 unsigned __int64 形式的二进制串和十六进制输出(64位有效的二进制数串)
void DisplayBin64(unsigned __int64 bin)
{
int i;
for(i=;i>=;i--){
printf("%d",(bin>>i) %);
}
printf("\n");
DisplayHex64(bin);
} //将 unsigned __int64 形式的二进制串和十六进制输出(48位有效的二进制数串)
void DisplayBin48(unsigned __int64 bin)
{
int i;
for(i=;i>=;i--){
printf("%d",(bin>>i) %);
}
printf("\n");
DisplayHex48(bin);
} //将 unsigned __int64 形式的二进制串和十六进制输出(32位有效的二进制数串)
void DisplayBin32(unsigned __int64 bin)
{
int i;
for(i=;i>=;i--){
printf("%d",(bin>>i) %);
}
printf("\n");
DisplayHex32(bin);
} //将 unsigned __int64 形式的二进制串和十六进制输出(28位有效的二进制数串)
void DisplayBin28(unsigned __int64 bin)
{
int i;
for(i=;i>=;i--){
printf("%d",(bin>>i) %);
}
printf("\n");
DisplayHex28(bin);
} /* ------------------------------ 【1】初始置换IP ------------------------------
* 把明文顺序打乱重新排列,置换输出为64位,
* 数据置换后的第一位,第二位分别是原来的58、50位
*/ unsigned __int64 InitReplace(unsigned __int64 bin) //初始置换IP
{
unsigned __int64 t = ;
int i;
for(i=;i<;i++){
t = t | ( (bin>>(-IP[i])) %) << (-i);
}
return t;
} /* ------------------------------ 【2】将置换输出的64位数据分成左右两半 ------------------------------
* 左一半称为L0,右一半称为R0,各32位。
*/ void DivideLR(unsigned __int64 binip,unsigned __int64 &L0,unsigned __int64 &R0) //将置换输出的64位数据分为L0(32位),R0(32位)两部分
{
unsigned __int64 one = ;
L0 = binip >> ;
R0 = binip % (one<<);
} /* ------------------------------ 【3】计算函数的16轮迭代 ------------------------------
* 1~16轮加密迭代
*/ //置换选择1,64->56
unsigned __int64 FunPC_1(unsigned __int64 bink)
{
unsigned __int64 binpc_1 = ;
int i;
for(i=;i<;i++)
binpc_1 |= ( (bink>>(-PC_1[i])) %) << (-i);
return binpc_1;
} //获得第i轮C,D,即Ci-1,Di-1 ==> Ci,Di
void getNextCD(int i,unsigned __int64 &C,unsigned __int64 &D)
{
unsigned __int64 t=,one=;
t = C >> (-LS[i]);
C = (C<<LS[i])%(one<<);
C |= t;
t = D >> (-LS[i]);
D = (D<<LS[i])%(one<<);
D |= t;
} //置换选择2,56->48
unsigned __int64 FunPC_2(unsigned __int64 t)
{
//获得子密钥k
unsigned __int64 k=;
int i;
for(i=;i<;i++)
k |= ( (t>>(-PC_2[i])) %) << (-i);
return k;
} //子密钥生成
void ProduceK(unsigned __int64 bink)
{
unsigned __int64 binpc_1,one=,C=,D=;
binpc_1 = FunPC_1(bink); //置换选择1 //分成2个28位
C = binpc_1 >> ;
D = binpc_1 % (one << ); int i;
for(i=;i<=;i++){
//确定子密钥K[i]
getNextCD(i,C,D);
printf("第%d轮:\n",i);
printf("C[%d] = ",i);
DisplayBin28(C);
printf("D[%d] = ",i);
DisplayBin28(D);
printf("\n"); unsigned __int64 t=;
t = ((C<<) | D)%(one<<);
K[i] = FunPC_2(t); //进行置换选择2,将56位->48位子密钥
}
} //扩展置换E,32->48
unsigned __int64 FunE(unsigned __int64 R)
{
unsigned __int64 t = ;
int i;
for(i=;i<;i++)
t |= ( (R>>(-E[i])) %) << (-i);
return t;
} //S盒代换
unsigned __int64 FunS(unsigned __int64 RX)
{
int x,y,i;
unsigned __int64 one = ,t,RS = ;
for(i=;i<;i++){
t = ( RX >> (*(-i)) ) % (one<<);
x = t>>;
x = (x<<) | (t%);
y = (t<<)%(one<<)>>;
RS = RS<< | S[i][x][y];
}
return RS;
} //置换P运算
unsigned __int64 FunP(unsigned __int64 RS)
{
unsigned __int64 RP = ;
int i;
for(i=;i<;i++)
RP |= ( (RS>>(-P[i])) %) << (-i);
return RP;
} //轮函数f(R,K)
unsigned __int64 f(int i,unsigned __int64 R,unsigned __int64 k)
{
unsigned __int64 RE,RX,RS,RP;
RE = FunE(R); //将32位Ri-1扩展置换为48位
RX = RE ^ k; //将48位RE与子密钥k异或运算
RS = FunS(RX); //S盒代换
RP = FunP(RS); //置换P运算
return RP;
} unsigned __int64 Iteration16(unsigned __int64 L0,unsigned __int64 R0) //进行16次迭代计算
{
int i;
unsigned __int64 Ri = R0;
unsigned __int64 Li = L0;
printf("L0=");
DisplayBin32(L0);
printf("R0=");
DisplayBin32(R0);
printf("\n");
for(i=;i<=;i++){
printf("第%d轮加密:\n",i);
unsigned __int64 t = Ri; //轮函数
Ri = f(i,Ri,K[i]);
printf("f(R%d,K%d)=",i-,i);
DisplayBin32(Ri); //Li-1和轮函数结果异或运算得到Ri
Ri = Li ^ Ri;
//轮函数运算结果即是Li
Li = t; //输出Li和Ri
printf("L%d=",i);
DisplayBin32(Li);
printf("R%d=",i);
DisplayBin32(Ri);
printf("\n");
} return Ri<< | Li;
} unsigned __int64 InverseIteration16(unsigned __int64 L0,unsigned __int64 R0) //进行逆16次迭代计算,为解密过程
{
int i;
unsigned __int64 Ri = R0;
unsigned __int64 Li = L0;
printf("L0=");
DisplayBin32(L0);
printf("R0=");
DisplayBin32(R0);
printf("\n");
for(i=;i>=;i--){
printf("第%d轮加密:\n",-i);
unsigned __int64 t = Ri; //轮函数
Ri = f(i,Ri,K[i]);
printf("f(R%d,K%d)=",i-,i);
DisplayBin32(Ri); //Li-1和轮函数结果异或运算得到Ri
Ri = Li ^ Ri;
//轮函数运算结果即是Li
Li = t; //输出Li和Ri
printf("L%d=",i);
DisplayBin32(Li);
printf("R%d=",i);
DisplayBin32(Ri);
printf("\n");
} return Ri<< | Li;
} /* ------------------------------ 【4】逆初始置换IP^-1 ------------------------------
* 把数据打乱重排,产生64位密文。
*/ unsigned __int64 InverseInitReplace(unsigned __int64 bin) //进行逆初始置换IP^-1
{
unsigned __int64 t = ;
int i;
for(i=;i<;i++){
t = t | ( (bin>>(-IP_1[i])) %) << (-i);
}
return t;
} void printOut(FILE* fo,unsigned __int64 bin)
{
char ans[]={},t=;
int i,cnt=;
for(i=;i>=;i--){
t = t<< | ((bin>>i)%);
if(i%==){
ans[cnt++] = t;
t = ;
}
}
fwrite(ans,,,fo);
} //加密函数
void Encryption()
{
//文件读入
FILE* fm = fopen(".\\Plaintext.txt","rb"); //明文文件
FILE* fk = fopen(".\\key.txt","r"); //密钥文件
FILE* fo = fopen(".\\Ciphertext.txt","wb"); //密文文件 if(fm==NULL){
printf("明文文件input.txt打开失败\n");
}
if(fk==NULL){
printf("密钥文件key.txt打开失败\n");
}
if(fo==NULL){
printf("加密后文件output.txt打开失败\n");
} unsigned char s[]={},key[]={};
int i; fscanf(fk,"%s",key); //读取密钥 while(fread(s,,,fm)){
printf("----------------------------------------------------------------------------\n");
printf("\n");
printf("当前读取的明文串为:\n");
printf("%s\n",s);
unsigned __int64 bin = bstr2bit(s); //将加密串转换为2进制形式
printf("\n");
unsigned __int64 bink = str2bit(key); //将密钥串转换为2进制形式
printf("\n"); //输出
printf("\n");
printf("【输入】\n");
printf("输入的二进制明文串:\n");
DisplayBin64(bin);
printf("输入的二进制密钥串:\n");
DisplayBin64(bink);
printf("\n"); //IP置换
printf("明文初始化置换后:\n");
unsigned __int64 binip = InitReplace(bin);
DisplayBin64(binip);
printf("\n"); //获得L0,R0
printf("将明文分割为L0,R0两部分:\n");
unsigned __int64 L0,R0;
DivideLR(binip,L0,R0); //将binip分割为L0和R0
//输出L0,R0
printf("L0为:");
DisplayBin32(L0);
printf("R0为:");
DisplayBin32(R0);
printf("\n"); //生成16个子密钥,并输出
printf("--------------- 子密钥生成过程 ---------------\n");
memset(K,,sizeof(K));
ProduceK(bink);
printf("生成的16个子密钥:\n");
for(i=;i<=;i++){
printf("K[%d]为 ",i);
DisplayBin48(K[i]);
//printf("\n");
}
printf("\n"); //16次加密迭代
printf("--------------- 16轮加密迭代 --------------- \n");
unsigned __int64 binIter = Iteration16(L0,R0);
printf("迭代加密后的结果:\n");
DisplayBin64(binIter);
printf("\n"); //逆初始置换IP_1
unsigned __int64 binip_1 = InverseInitReplace(binIter);
printf("最后,逆初始置换:\n");
DisplayBin64(binip_1);
printf("\n"); //输出最终加密结果
printf("【加密结果】\n明文 \"%s\" 的DES加密的结果为:\n",s);
DisplayBin64(binip_1); printf("\n");
printf("----------------------------------------------------------------------------\n");
printf("\n"); //将加密结果写到加密文件中
printOut(fo,binip_1); memset(s,,sizeof(s));
}
//文件关闭
fclose(fm);
fclose(fk);
fclose(fo);
} //解密函数
void Decryption()
{
//文件读入
FILE* fm = fopen(".\\Ciphertext.txt","rb"); //密文文件
FILE* fk = fopen(".\\key.txt","r"); //密钥文件
FILE* fo = fopen(".\\DecrypPlaintext.txt","wb"); //解密后文件 if(fm==NULL){
printf("密文文件 Ciphertext.txt 打开失败\n");
}
if(fk==NULL){
printf("密钥文件 key.txt 打开失败\n");
}
if(fo==NULL){
printf("解密后文件 DecrypPlaintext.txt 打开失败\n");
} unsigned char s[]={},key[]={};
int i; fscanf(fk,"%s",key); //读取密钥 while(fread(s,,,fm)){
printf("----------------------------------------------------------------------------\n");
printf("\n");
printf("当前读取的密文串为:\n");
printf("%s\n",s);
unsigned __int64 bin = bstr2bit(s); //将密文串转换为2进制形式
printf("\n");
unsigned __int64 bink = str2bit(key); //将密钥串转换为2进制形式
printf("\n"); //输出
printf("----------------------------------------------------------------------------\n");
printf("\n");
printf("【输入】\n");
printf("输入的二进制密文串:\n");
DisplayBin64(bin);
printf("输入的二进制密钥串:\n");
DisplayBin64(bink);
printf("\n"); //IP置换
printf("密文初始化置换后:\n");
unsigned __int64 binip = InitReplace(bin);
DisplayBin64(binip);
printf("\n"); //获得L0,R0
printf("将密文分割为L0,R0两部分:\n");
unsigned __int64 L0,R0;
DivideLR(binip,L0,R0); //将binip分割为L0和R0
//输出L0,R0
printf("L0为:");
DisplayBin32(L0);
printf("R0为:");
DisplayBin32(R0);
printf("\n"); //生成16个子密钥,并输出
printf("--------------- 子密钥生成过程 ---------------\n");
memset(K,,sizeof(K));
ProduceK(bink);
printf("生成的16个子密钥:\n");
for(i=;i<=;i++){
printf("K[%d]为 ",i);
DisplayBin48(K[i]);
//printf("\n");
}
printf("\n"); //16次加密迭代
printf("--------------- 16轮加密迭代 --------------- \n");
unsigned __int64 binIter = InverseIteration16(L0,R0);
printf("迭代解密后的结果:\n");
DisplayBin64(binIter);
printf("\n"); //逆初始置换IP_1
unsigned __int64 binip_1 = InverseInitReplace(binIter);
printf("最后,逆初始置换:\n");
DisplayBin64(binip_1);
printf("\n"); //输出最终加密结果
printf("【解密结果】\n密文 \"%s\" 的DES解密的结果为:\n",s);
DisplayBin64(binip_1); printf("\n");
printf("----------------------------------------------------------------------------\n"); //将加密结果写到加密文件中
printOut(fo,binip_1); memset(s,,sizeof(s));
}
//文件关闭
fclose(fm);
fclose(fk);
fclose(fo);
} int Menu(int &Case)
{
int in; FILE* fk = fopen(".\\key.txt","r"); //密钥文件
if(fk==NULL){
printf("密钥文件key.txt打开失败\n");
} unsigned char key[];
fscanf(fk,"%s",key); //读取密钥
unsigned __int64 bink = str2bit(key); //将密钥串转换为2进制形式
printf("【%d】当前密钥(key)为:(二进制形式)\n",Case++);
DisplayBin64(bink);
printf("(密钥存储在 key.txt 中)\n");
printf("\n"); printf("请选择,是使用DES算法加密还是解密?\n");
printf("(加密过程:Plaintext.txt => Ciphertext.txt\n");
printf(" 解密过程:Ciphertext.txt => DecrypPlaintext.txt )\n");
printf("[1] 加密\n");
printf("[2] 解密\n");
printf("[0] 退出程序\n"); scanf("%d",&in);
getchar();
fflush(stdin); // 清空缓冲区 if(in== || in== || in==){
return in;
}
else{
printf("输入错误,请重新输入!\n");
printf("\n");
printf("----------------------------------------------------------------------------\n");
printf("\n");
return -;
}
} /*
* 主函数
*/
int main()
{
int Case=,in;
while(){
in = Menu(Case);
switch(in){
case -: //输入错误,进入下次循环
break;
case : //退出程序
printf("谢谢使用 :)\n");
return ;
case : //加密
Encryption();
break;
case : //解密
Decryption();
break;
}
}
return ;
}
Freecode : www.cnblogs.com/yym2013
DES加密算法实现的更多相关文章
- 在.NET Core 里使用 BouncyCastle 的DES加密算法
.NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用 ...
- 浅谈DES加密算法
一.DES加密算法介绍 1.要求密钥必须是8个字节,即64bit长度 2.因为密钥是byte[8] , 代表字符串也可以是非可见的字节,可以与Base64编码算法一起使用 3.加密.解密都需要通过字节 ...
- JAVA使用DES加密算法加密解密
程序中使用了.properties文件作为参数配置文档,好处是灵活配置各项参数 一旦对数据库的一些参数进行了配置,势必涉及数据库的IP,端口,用户名和密码 properties文件全是unicode编 ...
- 对称密码——DES加密算法
前言 本篇博文将介绍对称密码算法中的DES密码的算法原理与代码实现(Java) DES算法原理 DES加密算法是对称加密算法(加密和解密使用同一个密钥)中的一种,DES也是分组密码,以64位为分组对明 ...
- des加密算法java&c#
项目中用到的数据加密方式是ECB模式的DES加密得到的十六进制字符串.技术支持让写一个.net版的加密算法.这里做一下记录. java版: 16进制使用的是bouncycastle. import c ...
- android和.net webservice中的DES加密算法
也是看了一堆的例子,本身并不会写加密算法,好在只要会用就行了,我们把在app中使用的参数加密,然后在.net端的webservice中进行解密,本身并没有什么问题,但是android下和.net下的d ...
- DES加密算法的C++实现
<信息安全技术>这门课又在讲 DES 加密算法了,以前用纯C写过一次,这次我用 C++ 重新写了一个,写篇文章以备后用.本文介绍了 DES 算法加密的大致步骤和整体流程. 一.DES算法原 ...
- .net中DES加密算法研究
/// <summary> /// DES加密算法 /// </summary> /// <param name="toEncrypt">要加密 ...
- 使用 JavaScriptService 在.NET Core 里实现DES加密算法
文章<ASP.NET Core love JavaScript>和<跨平台的 NodeJS 组件解决 .NetCore 不支持 System.Drawing图形功能的若干问题> ...
- DES加密算法
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1976年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),随后在国际上广泛流传开 ...
随机推荐
- django 的文件上传
template html(模板文件): <form enctype="multipart/form-data" method="POST" action ...
- 术&道
技术分为术和道两种. 具体做事的方法为术:做事的原理和原则是道. 追求术的人一辈子工作很辛苦,只有掌握了道的本质和精髓才能永远游刃有余. 在纷繁的选择面前, 不知到哪些是对的没关系, 知道哪些是不好的 ...
- 烂泥:php5.6源码安装及php-fpm配置
LNMP环境的搭建中,现在只有php没有源码安装过.这篇文章就把这个介绍下. 注意本篇文章使用的centos 6.5 64bit. 登陆centos下载php5.6的安装包.php的软件包可以去国内的 ...
- JavaScript——Prototype详探
用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...
- pip安装简单方法
前提:有网络 wget -c --no-check-certificate https://bootstrap.pypa.io/get-pip.py python get-pip.py
- checksum table 【转】
来自:http://dinglin.iteye.com/blog/1791922 有同学问到 checksum table在逻辑备份时候前后是否可以用于验证数据一致性.扩展一下发现有一些有趣的问题,比 ...
- 9.SpringMVC和json结合传递参数
input的值一定要用.attribute来取值.val( )只能用可以看看开源社区jQuery的ajax请求.html():读取和修改一个元素的HTML内容,详情.html():.text():读取 ...
- HDU 4949 Light(插头dp、位运算)
比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...
- 【python】入门学习(五)
字符串: 正索引,从0开始 和 负索引,从-1开始 >>> s = 'apple' >>> s[0] 'a' >>> s[1] 'p' >& ...
- 【python】An Introduction to Interactive Programming in Python(week two)
This is a note for https://class.coursera.org/interactivepython-005 In week two, I have learned: 1.e ...