人们在单一恺撒密码的基础上扩展出多表密码,称为“维吉尼亚”密码。是法国密码学家维吉尼亚在1586年提出的一种多表替代密码,维吉尼亚密码引入了“密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。
下面就让我们来用安卓技术,在Android平台上进行加解密的实现:
首先进行创建一个项目,其加密布局文件代码如下图所示,
其中textView_inform用于显示加解密类型,relative_miyue_ptc用于添加密钥所使用的组件,et_plainttext为明文,即要加密的字符,btn_plainttexttociphertext按钮是实现点击事件
<TextView android:id="@+id/textView_inform" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:text="对象类型" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/relative_miyue_ptc" android:layout_below="@+id/textView_inform" > </RelativeLayout> <EditText android:id="@+id/et_plaintext" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView_inform" android:layout_alignParentBottom="true" android:ems="10" android:hint="这是明文..." android:inputType="textMultiLine" android:textColor="#007700" > <requestFocus /> </EditText> <Button android:id="@+id/bn_plaintexttociphertext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@+id/textView_inform" android:layout_below="@+id/textView_inform" android:layout_marginTop="18dp" android:alpha="0.8" android:background="@drawable/upomp_bypay_btn_big_bg_click" android:text="加密" />解密布局文件和加密类似,仅仅是按钮上显示的字符不同,在这就不贴出来了。
下面来实现加密过程:
//维吉尼亚加密方式 et_plaintext.setText(str_isctp); //将从解密界面传来的数据放置到文本编辑框中 System.out.println("选择的是" + passIntent.x + "\t" + passIntent.y+ " :"+passIntent.name_intent); //绑定布局文件 RelativeLayout relative=(RelativeLayout) findViewById(R.id.relative_miyue_ptc); //添加密钥组件,用于输入密钥 final EditText et_miyue=new EditText(this); et_miyue.setId(24); et_miyue.setHint("请输入密钥..."); et_miyue.setSingleLine(true); relative.addView(et_miyue); ///////////////////////////////////////////// bn_plaintexttociphertext.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (v.isPressed())// 加密 { // 获取密钥和明文 String miyue = et_miyue.getText().toString(); String str_p = et_plaintext.getText().toString(); char[] miyue_c = null; char[] str_p_char = null; int k = 0; if (miyue.isEmpty()||str_p.isEmpty()) { Toast.makeText(Result_PTC.this, "请输入密钥或明文...",1).show(); } else { try { miyue_c = miyue.toCharArray(); str_p_char = str_p.toCharArray(); } catch (Exception e) { System.out.println("Exception"); } int len = str_p_char.length; int len_miyue_c = miyue_c.length; int i_miyue=0; for (int j = 0; j < len; j++) { if (str_p_char[j] >= 'a'&& str_p_char[j] <= 'z') { k = miyue_c[i_miyue%len_miyue_c] - 'a'; i_miyue++; int value_ascii = (((str_p_char[j]-'a'+k))%26)+'a'; str_p_char[j] = (char) (value_ascii); } else { str_p_char[j] = str_p_char[j]; } } StringBuffer sb = new StringBuffer(); for (int i = 0; i < len; i++) { sb.append(str_p_char[i]); } str_p = sb.toString(); et_plaintext.setEnabled(true); Toast.makeText(Result_PTC.this,"已加密...", Toast.LENGTH_SHORT).show(); // 创建一个意图 Intent intent = new Intent(Result_PTC.this,Result_CTP.class); // 传递自定义数据 // 第一种传值方式,创建一个Bundle对象 // 传递自定义数据 PassIntent passIntent = new PassIntent(); passIntent.id_opt = id_opt; passIntent.x = ptc_x; passIntent.y = ptc_y; passIntent.name_intent = ptc_name_intent; passIntent.str_ptc = str_p; intent.putExtra("passIntent",passIntent); // 启动另外一个Activity startActivity(intent); finish(); } } } }); }下面是解密方式的源代码:
//维吉尼亚解密方式 System.out.println("选择的是" + passIntent.x + "\t" + passIntent.y+ " :"+passIntent.name_intent); et_ciphertext.setText(str_isptc); //绑定布局文件 RelativeLayout relative=(RelativeLayout) findViewById(R.id.relative_miyue_ctp); //添加密钥组件,用于输入密钥 final EditText et_miyue=new EditText(this); et_miyue.setId(25); et_miyue.setHint("请输入密钥..."); et_miyue.setSingleLine(true); relative.addView(et_miyue); bn_ciphertexttoplaintext.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (v.isPressed())// 解密 { String miyue=et_miyue.getText().toString(); String str_c = et_ciphertext.getText().toString(); char []miyue_c=null; char []str_c_char = null; int k=0; if(miyue.isEmpty()||str_c.isEmpty()) { Toast.makeText(Result_CTP.this, "请输入密钥或密文...",1).show(); } else { try { miyue_c=miyue.toCharArray(); str_c_char=str_c.toCharArray(); } catch(Exception e) { System.out.println("Exception"); } int len=str_c_char.length; int len_miyue_c=miyue_c.length; int i_miyue=0; for(int j=0;j<len;j++) { //输出得到的字符串,也就是从文本编辑框得到的密文 //System.out.println("str_c_char["+j+"]:"+str_c_char[j]); //对明文进行加密 if(str_c_char[j]>='a'&&str_c_char[j]<='z') { k=miyue_c[i_miyue%len_miyue_c]-'a'; //System.out.println("miyue_c["+i_miyue+"]:"+miyue_c[i_miyue%len_miyue_c]); i_miyue++; int temp=(str_c_char[j]-'a')-k; if(temp>=0) { int value_ascii=((temp)%26)+'a'; str_c_char[j]=(char) (value_ascii); } else { int value_ascii=((temp+26)%26)+'a'; str_c_char[j]=(char) (value_ascii); } } } StringBuffer sb = new StringBuffer(); for(int i = 0; i <len; i++) { sb. append(str_c_char[i]); } str_c = sb.toString(); System.out.println("解密后的字符串:"+str_c); et_ciphertext.setEnabled(true); Toast.makeText(Result_CTP.this, "已解密...",Toast.LENGTH_SHORT).show(); ///////直接转入到加密后的文件中 //创建一个意图 Intent intent=new Intent(Result_CTP.this,Result_PTC.class); //传递自定义数据 //第一种传值方式,创建一个Bundle对象 //传递自定义数据 PassIntent passIntent=new PassIntent(); passIntent.id_opt= id_opt; passIntent.x=ctp_x; passIntent.y=ctp_y; passIntent.name_intent=ctp_name_intent; passIntent.str_ctp=str_c; intent.putExtra("passIntent", passIntent); //启动另外一个Activity startActivity(intent); finish(); } } } }); }
代码中PassIntent是一个接口类,页面之间数据的传递,读者可以直接使用Intent传值的其他几种方式代替。
下面为加解密效果图:
图1 密钥及要加密的文本
图2 加密后的文本显示
图 3 还原后的文本显示
以上就是对维吉尼亚密码加解密方式的实现,其具体原理可参见:信息安全技术中的维吉尼亚加密技术