Base64学习
b1、b2、b3代表普通的字符串,如”a”,”b”,”c”
n1、n2、n3、n4代表用Base64编码后的字符
“abc” -> “YWJj”
图中可以看到,普通的字符是8个bit,Base64字符是6个bit
对字符串进行Base64编码:
- 1、把待编码的字符串转换成二进制字符串 binStr
- 2、末位加0使得binStr.length能被6整除(Base64字符每个字符对应6个bit)
- 3、每6个bit组成unitBinStr 将unitBinStr转成int,从Base64表中取出对应字符并拼接
- 4、拼接完后的Base64字符串,如果长度不能被4整除,末位补=
private val codeStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxzy0123456789+/"
private fun encodeBase64(string: String): String {
//1、将待编码的字符串的每个字符转成二进制,不足8位高位补0,拼接起来
var str = str2BinaryStr(string)
var remainder = 0
if (str.length % 6 != 0) {
//2、一个Base64字符包含6个bit,不足6个的末位补0
remainder = 6 - (str.length % 6)
str += createZero(remainder)
//println(str)
}
val result = StringBuilder()
//3、6个bit一组,进行Base64字符转换
for (i in 0 until str.length step 6) {
if (i >= (str.length - remainder)) break
val item = str.substring(i, i + 6)
// 4、把二进制字符转成对应的整数
val tenCode = item.toInt(2)
//println(tenCode)
//5、从Base64表中取出整数对应的Base64字符
result.append(codeStr[tenCode])
}
//6、校验Base64字符串的长度是否是4的倍数,不是,末位补=
val groupRemainder = (str.length / 6) % 4
if (groupRemainder != 0) {
result.append(createEqual(4 - groupRemainder))
}
return result.toString()
}
将Base64字符串解码:
private fun decodeBase64(string: String): String {
//1、去掉末位=号
val str = string.filter { it != '=' }
var intNum = -1
var oldBinaryStr = ""
var decodeString = ""
//2、得到原始的二进制字符串(有可能末位补过0)
str.forEach {
//从Base64表中取出Base64对应的index
intNum = codeStr.indexOf(it)
//将index转成二进制
var binStr = intNum.toString(2)
//注意这里是不足6补0而不是不足8 因为Base64每个字符对应6个bit
if (binStr.length < 6) {
binStr = createZero(6 - binStr.length) + binStr
}
//拼接成原始的二进制字符串(有可能末位补过0)
oldBinaryStr += binStr
}
//3、去掉末位补的0
val tail = oldBinaryStr.length % 6
if (tail != 0) {
oldBinaryStr = oldBinaryStr.substring(0, oldBinaryStr.length - (6 - tail))
}
//4、8个bit一组得到原始字符串
for (i in 0..oldBinaryStr.length step 8) {
if (i >= (oldBinaryStr.length - tail)) break
val oldInt = oldBinaryStr.substring(i, i + 8).toInt(2)
decodeString += oldInt.toChar()
}
//println(decodeString)
return decodeString
}
其他辅助函数:
fun Char.getBinary(): String {
val value = this.toInt()
var quotient = value
var remainder = 0
val result = StringBuilder()
while (quotient > 0) {
remainder = quotient % 2
quotient /= 2
result.append(remainder)
}
return result.reverse().toString()
}
fun createZero(count: Int): String {
if (count == 0) {
return ""
}
val sb = StringBuilder()
for (i in 0 until count) {
sb.append("0")
}
return sb.toString()
}
fun createEqual(count: Int): String {
if (count == 0) {
return ""
}
val sb = StringBuilder()
for (i in 0 until count) {
sb.append("=")
}
return sb.toString()
}