io.jsonwebtoken.impl.Base64UrlCodec Maven / Gradle / Ivy
/*
* Copyright (C) 2014 jsonwebtoken.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.jsonwebtoken.impl;
public class Base64UrlCodec extends AbstractTextCodec {
@Override
public String encode(byte[] data) {
String base64Text = TextCodec.BASE64.encode(data);
byte[] bytes = base64Text.getBytes(US_ASCII);
//base64url encoding doesn't use padding chars:
bytes = removePadding(bytes);
//replace URL-unfriendly Base64 chars to url-friendly ones:
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] == '+') {
bytes[i] = '-';
} else if (bytes[i] == '/') {
bytes[i] = '_';
}
}
return new String(bytes, US_ASCII);
}
protected byte[] removePadding(byte[] bytes) {
byte[] result = bytes;
int paddingCount = 0;
for (int i = bytes.length - 1; i > 0; i--) {
if (bytes[i] == '=') {
paddingCount++;
} else {
break;
}
}
if (paddingCount > 0) {
result = new byte[bytes.length - paddingCount];
System.arraycopy(bytes, 0, result, 0, bytes.length - paddingCount);
}
return result;
}
@Override
public byte[] decode(String encoded) {
char[] chars = encoded.toCharArray(); //always ASCII - one char == 1 byte
//Base64 requires padding to be in place before decoding, so add it if necessary:
chars = ensurePadding(chars);
//Replace url-friendly chars back to normal Base64 chars:
for (int i = 0; i < chars.length; i++) {
if (chars[i] == '-') {
chars[i] = '+';
} else if (chars[i] == '_') {
chars[i] = '/';
}
}
String base64Text = new String(chars);
return TextCodec.BASE64.decode(base64Text);
}
protected char[] ensurePadding(char[] chars) {
char[] result = chars; //assume argument in case no padding is necessary
int paddingCount = chars.length % 4;
if (paddingCount > 0) {
result = new char[chars.length + paddingCount];
System.arraycopy(chars, 0, result, 0, chars.length);
for (int i = 0; i < paddingCount; i++) {
result[chars.length + i] = '=';
}
}
return result;
}
}