WUSTOJ 1324: Base64 Coding(Java)未解决,求题解
题目链接:1324: Base64 Coding
资料:ASCII码表
原文是英文,而且篇幅较长。因此下面不粘贴原文,只写中文大意。
Description
Base64是一种编码算法。它的工作原理是将 ASCII 码在 0x00 和 0xFF 之间的字符转换成只有小写字母、大写字母和数字组成的字符串,从而避免了编码的歧义问题。
让我们看一个简单的例子。
转换前:10101101 10111010 01110110
转换后:00101011 00011011 00101001 00110110
它们在转换后的十进制的值分别为 43、27、41 和 54,对应的字符分别为 “r”、“b”、“p” 和 “2”。查看对照表。所以我们说 24 位二进制字符串的 Base64 编码是 ‘rbp2’ 。解码算法是简单地删除每个字节的两个前缀 0 ,然后将它们连接在一起。
但是,如果原始文本的字节数不是 3 的倍数,应该怎么办?解决方案是我们将添加冗余的 0 ,Base64 编码将使用 ‘=’ 来表示这些 0 。这就是为什么有些 Base64 编码的字符串以一两个 ‘=’ 结尾。
如果结果字符串太长,每行放置76个字符。
想想托马斯霍布斯(Thomas Hobbes)的《利维坦》(Leviathan)中的那句名言吧。
人之所以与众不同,不仅因为他的理性,还因为他与其他动物的这种独特的激情,那就是一种精神上的欲望,因为他对持续不断的、不知疲倦的知识的创造所表现出来的喜悦的毅力,超过了任何肉体上短暂的强烈的快乐。
Base64 编码后,如下所示。
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
现在,您要对消息进行编码或解码。
Input
有多个测试用例。测试用例以 “#exit#” 结束,不应该处理它。
每个测试用例都以包含 “#b2s#” 或 “#s2b#” 的行开始,表示要对输入字符串执行解码或编码操作。每个测试用例都以 “#CaseEnd#” 结束。中间的字符串是要处理的字符。字符串的长度小于106。
Output
在单行中打印 “Case #id”,其中 “id” 是从 1 开始编号的用例号,然后输出结果字符串。
Sample Input
#s2b#
C^$AL6N20)QQ[IKSF;\',^9D>-<&W'>S2-(#[+F?#:
#CaseEnd#
#b2s#
NVA6PV4xRU5XQSJSPD0nVzRFRlYhPSE4WQ==
#CaseEnd#
#exit#
Sample Output
Case #1
Q14kQUw2TjIwKVFRW0lLU0Y7XCcsXjlEPi08JlcnPlMyLSgjWytGPyM6
Case #2
5P:=^1ENWA"R<='W4EFV!=!8Y
HINT
在 “#b2s#” 或 “#s2b#” 之后和 “#CaseEnd#” 之前的换行字符不需要处理。其他字符则被视为普通字符。
Base64 编码表:
| 十进制 | 字符 | 十进制 | 字符 | 十进制 | 字符 |
|---|---|---|---|---|---|
| 0 | A | 26 | a | 52 | 0 |
| 1 | B | 27 | b | 53 | 1 |
| 2 | C | 28 | c | 54 | 2 |
| 3 | D | 29 | d | 55 | 3 |
| 4 | E | 30 | e | 56 | 4 |
| 5 | F | 31 | f | 57 | 5 |
| 6 | G | 32 | g | 58 | 6 |
| 7 | H | 33 | h | 59 | 7 |
| 8 | I | 34 | i | 60 | 8 |
| 9 | J | 35 | j | 61 | 9 |
| 10 | K | 36 | k | 62 | + |
| 11 | L | 37 | l | 63 | / |
| 12 | M | 38 | m | ||
| 13 | N | 39 | n | ||
| 14 | O | 40 | o | ||
| 15 | P | 41 | p | ||
| 16 | Q | 42 | q | ||
| 17 | R | 43 | r | ||
| 18 | S | 44 | s | ||
| 19 | T | 45 | t | ||
| 20 | U | 46 | u | ||
| 21 | V | 47 | v | ||
| 22 | W | 48 | w | ||
| 23 | X | 49 | x | ||
| 24 | Y | 50 | y | ||
| 25 | Z | 51 | z |
分析
import java.util.Base64这个类,OJ目前不支持,所以不能用API,只能自己写。
代码
/**
* Time ms
* @author wowpH
* @version 4.0
* @date 2019年6月28日上午8:48:29
* Environment: Windows 10
* IDE Version: Eclipse 2019-3
* JDK Version: JDK1.8.0_112
*/
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
private final char[] BASE64_TABLE = { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', '+', '/' };
private Scanner sc = new Scanner(new InputStreamReader(System.in));
public Main() {
int caseNum = 1;// 用例号
while (sc.hasNext()) {
String operation = sc.nextLine();// 三种操作,编码,解码,退出
if (operation.contentEquals("#s2b#")) { // 编码
String message = input(); // 获取要编码的文本
output(code(message), caseNum); // 编码后输出
} else if (operation.contentEquals("#b2s#")) {// 解码
String message = input(); // 获取要解码的文本
output(decode(message), caseNum); // 解码后输出
} else if (operation.contentEquals("#exit#")) {// 退出
break;
}
++caseNum;
}
sc.close();
}
private String input() {// 获得需要转换的信息字符串
StringBuffer sb = new StringBuffer();
String temp = sc.nextLine();
while (false == temp.contentEquals("#CaseEnd#")) {
sb.append(temp);
temp = sc.nextLine();
}
return sb.toString();
}
private String code(String message) {// 编码
char[] messArr = message.toCharArray();// 字符串转成字符数组
StringBuffer binarySB = new StringBuffer(messArr.length * 8);// 存储二进制字符串
for (int i = 0; i < messArr.length; ++i) {
String oneByte = Integer.toBinaryString(messArr[i]);// 字符转成二进制字符串
for (int j = 8 - oneByte.length(); j > 0; --j) {
binarySB.append('0');// 不足8位,前面补'0'
}
binarySB.append(oneByte);
}
// 原始文本不是3的倍数,即二进制串长度不是6的倍数,末尾添加冗余的'0'
int remainder = binarySB.length() / 8 % 3;
if (1 == remainder) {
binarySB.append("0000");
} else if (2 == remainder) {
binarySB.append("00");
}
int length = binarySB.length();
StringBuffer ans = new StringBuffer(length / 6);// 存储转换后的字符串
for (int i = 0; i < length; i += 6) {
String indexStr = binarySB.substring(i, i + 6);// 获取6位二进制串
int index = Integer.parseInt(indexStr, 2);// 解析成10进制数
ans.append(BASE64_TABLE[index]);// 查找对照表,添加对应字符
}
// 末尾添加'='
if (1 == remainder) {
ans.append("==");
} else if (2 == remainder) {
ans.append("=");
}
return ans.toString();// 返回编码后的字符串
}
private String decode(String message) {// 解码
char[] messArr = message.toCharArray();// 字符串转成字符数组
StringBuffer binarySB = new StringBuffer(messArr.length * 6);// 存储二进制串
for (int i = 0; i < messArr.length; ++i) {
int index = parse(messArr[i]);// 获取字符的Base64编码的十进制值
String oneByte = Integer.toBinaryString(index);// 转成二进制串
for (int j = 6 - oneByte.length(); j > 0; --j) {
binarySB.append('0');// 不足6位,前面补'0'
}
binarySB.append(oneByte);
}
int length = binarySB.length();
StringBuffer ans = new StringBuffer(length / 8);// 存储解码后的字符串
for (int i = 0; i < length; i += 8) {
String str = binarySB.substring(i, i + 8);// 获取8位二进制串
int number = Integer.parseInt(str, 2);// 解析成十进制数,也就是ASCII码值
ans.append((char) number);// 转成字符
}
if ('=' == messArr[messArr.length - 1]) {
if ('=' == messArr[messArr.length - 2]) {
return ans.substring(0, ans.length() - 2);
}
return ans.substring(0, ans.length() - 1);
}
return ans.toString();// 返回解码后的字符串
}
private int parse(char ch) {// 获取字符的Base64码值,十进制
int index = 64;// 默认越界
if ('+' == ch) {
index = 62;
} else if ('/' == ch) {
index = 63;
} else if ('=' == ch) {
index = 0;
} else if (ch >= 'A' && ch <= 'Z') {
index = ch - 'A' + 0;
} else if (ch >= 'a' && ch <= 'z') {
index = ch - 'a' + 26;
} else if (ch >= '0' && ch <= '9') {
index = ch - '0' + 52;
}
return index;
}
private void output(String string, int caseNum) {// 输出用例caseNum的结果string
System.out.println("Case #" + caseNum);
int quotients = string.length() / 76;// 每行最多76个字符
for (int i = 0; i < quotients; ++i) {
System.out.println(string.substring(i * 76, i * 76 + 76));
}
System.out.println(string.substring(quotients * 76));
}
public static void main(String[] args) {
new Main();
}
}
版权声明
- 转载、参考、引用必须在首页添加如下文字:
[WUSTOJ 1324: Base64 Coding(Java)未解决,欢迎大家讨论——wowpH](https://blog.csdn.net/pfdvnah/article/details/93536467) - 代码原创,公开引用不能删除首行注释(作者,版本号,时间等信息);
- 如果有疑问欢迎评论区留言,尽量解答;
- 如果有错误,还望大侠评论区指正。
WUSTOJ 1324: Base64 Coding(Java)未解决,求题解的更多相关文章
- 记一次未解决的异常:java.lang.NoClassDefFoundError: net/sf/json/JSONObject
原因:Jetty会导致这个问题,Tomcat可以正常启动 一.异常产生现象 使用json-lib转换实体类/字符串,跑单元测试没问题,但是启动jetty后调用JSONArray.fromObjec ...
- oracle,wamp,FZ突然出现问题,求解决方案(未解决,最终系统还原)
-----背景------- 系统:win7 64位oracle 11g(11.1)每天都用oracle.用toad for oracle .电脑固定IP.未更改任何配置信息.用了几个月,突然出现了 ...
- [未解决]Exception in thread "main" java.lang.IllegalArgumentException: offset (0) + length (8) exceed the capacity of the array: 6
调用这个方法 是报错,未解决 binfo.setTradeAmount(Double.parseDouble(new String(result.getValue(Bytes.toBytes(fami ...
- IDEA Error:java: 未结束的字符串文字
首页 > 编程交流 > 基础篇 > IDEA Error:java: 未结束的字符串文字 201601-25 IDEA Error:java: 未结束的字符串文字 IDEA开发, ...
- 报错:(未解决)Opening socket connection to server master/192.168.52.26:2181. Will not attempt to authenticate using SASL (unknown error)
报错背景: CDH集群中,将kafka和Flume整合,将kafka的数据发送给Flume消费. 启动kafka的时候正常,但是启动Flume的时候出现了报错现象. 报错现象: DH--.cdh5./ ...
- WUSTOJ 1285: Factors(Java)
1285: Factors 参考 hadis_fukan的博客--wustoj 1285 Factors 题目 输入一个数n,找出1~n之间(包括1,n)的质因子最多的数(x)的质因子个数(f ...
- OpenCV在ARM-linux上的移植过程遇到的问题3---共享库中嵌套库居然带路径【未解决】
[Linux开发]OpenCV在ARM-linux上的移植过程遇到的问题3-共享库中嵌套库居然带路径[未解决] 标签(空格分隔): [Linux开发] 移植opencv到tq2440 一.下载open ...
- (未解决)flume监控目录,抓取文件内容推送给kafka,报错
flume监控目录,抓取文件内容推送给kafka,报错: /export/datas/destFile/220104_YT1013_8c5f13f33c299316c6720cc51f94f7a0_2 ...
- 面向对象第一单元总结:Java实现表达式求导
面向对象第一单元总结:Java实现表达式求导 题目要求 输入一个表达式:包含x,x**2,sin(),cos(),等形式,对x求导并输出结果 例:\(x+x**2+-2*x**2*(sin(x**2+ ...
随机推荐
- Column 'status' specified twice
字段写了两次, 检查下sql语句, 删除一个就好了.
- U盘量产过程PS2251-07(PS2307) - F/W 01.05.10 [2014-05-23]
说明本篇文章可能无法解决你的问题,请谨慎尝试.本博客中使用的工具提供下载(如果没有积分,可联系作者免费获取)ChipGenius_v4_00_0030UPTool_v2.089起因 U盘原先正常使用, ...
- 微信小程序丨将溢出的文本用省略号代替的方法
下面进入正题,有关于将溢出的文本用省略号代替的方法,不知道什么原因,我的程序用传统的代码无法解决: .text{ white-space: nowrap; overflow: hidden; text ...
- Hive的配置详解和日常维护
Hive的配置详解和日常维护 一.Hive的参数配置详解 1>.mapred.reduce.tasks 默认为-1.指定Hive作业的reduce task个数,如果保留默认值,则Hive 自 ...
- openresty开发系列10--openresty的简单介绍及安装
openresty开发系列10--openresty的简单介绍及安装 一.Nginx优点 十几年前,互联网没有这么火,软件外包开发,信息化建设,帮助企业做无纸化办公,收银系统,工厂erp,c/s架构偏 ...
- 使用ffmpeg.exe进行转码参数说明
使用ffmpeg.exe进行转码参数说明 摘自:https://blog.csdn.net/coloriy/article/details/47337641 2015年08月07日 13:04:32 ...
- RabbitMQ 入门教程(PHP版) 第四部分:路由(Routing)
路由(Routing) 在前面的第三部分教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重 ...
- Linux的桌面虚拟化技术KVM(三)——KVM虚拟机克隆和快照
Linux的桌面虚拟化技术KVM(一)——新建KVM虚拟机 Linux的桌面虚拟化技术KVM(二)——远程桌面管理 (1).KVM虚拟机克隆 KVM虚拟克隆命令virt-clone [选项] 常用选项 ...
- Python中random模块生成随机数详解
Python中random模块生成随机数详解 本文给大家汇总了一下在Python中random模块中最常用的生成随机数的方法,有需要的小伙伴可以参考下 Python中的random模块用于生成随机数. ...
- /var/spool/postfix
centos磁盘优化,发现/var/spool/postfix/maildrop下有大量文件. cron进程默认会将计划任务中所运行的脚本的警告.错误信息或者脚本输出信息发送给计划任务的所有者,而由于 ...