B64.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.codec.digest;

  18. import java.security.SecureRandom;
  19. import java.util.Random;

  20. /**
  21.  * Base64-like method to convert binary bytes into ASCII chars.
  22.  * <p>
  23.  * TODO: Can Base64 be reused?
  24.  * </p>
  25.  * <p>
  26.  * This class is immutable and thread-safe.
  27.  * </p>
  28.  */
  29. final class B64 {

  30.     /**
  31.      * Table with characters for Base64 transformation.
  32.      */
  33.     static final String B64T_STRING = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

  34.     /**
  35.      * Table with characters for Base64 transformation.
  36.      */
  37.     static final char[] B64T_ARRAY = B64T_STRING.toCharArray(); // package access for testing
  38.     // N.B. Do not make this protected or public. Array contents are mutable!

  39.     /**
  40.      * Base64 like conversion of bytes to ASCII chars.
  41.      *
  42.      * @param b2
  43.      *            A byte from the result.
  44.      * @param b1
  45.      *            A byte from the result.
  46.      * @param b0
  47.      *            A byte from the result.
  48.      * @param outLen
  49.      *            The number of expected output chars.
  50.      * @param buffer
  51.      *            Where the output chars is appended to.
  52.      */
  53.     static void b64from24bit(final byte b2, final byte b1, final byte b0, final int outLen,
  54.                              final StringBuilder buffer) {
  55.         // The bit masking is necessary because the JVM byte type is signed!
  56.         int w = b2 << 16 & 0x00ffffff | b1 << 8 & 0x00ffff | b0 & 0xff;
  57.         // It's effectively a "for" loop but kept to resemble the original C code.
  58.         int n = outLen;
  59.         while (n-- > 0) {
  60.             buffer.append(B64T_ARRAY[w & 0x3f]);
  61.             w >>= 6;
  62.         }
  63.     }

  64.     /**
  65.      * Generates a string of random chars from the B64T set.
  66.      * <p>
  67.      * The salt is generated with {@link SecureRandom}.
  68.      * </p>
  69.      *
  70.      * @param num Number of chars to generate.
  71.      * @return a random salt {@link String}.
  72.      */
  73.     static String getRandomSalt(final int num) {
  74.         return getRandomSalt(num, new SecureRandom());
  75.     }

  76.     /**
  77.      * Generates a string of random chars from the B64T set.
  78.      * <p>
  79.      * The salt is generated with the {@link Random} provided.
  80.      * </p>
  81.      *
  82.      * @param num Number of chars to generate.
  83.      * @param random an instance of {@link Random}.
  84.      * @return a random salt {@link String}.
  85.      */
  86.     static String getRandomSalt(final int num, final Random random) {
  87.       final StringBuilder saltString = new StringBuilder(num);
  88.       for (int i = 1; i <= num; i++) {
  89.         saltString.append(B64T_STRING.charAt(random.nextInt(B64T_STRING.length())));
  90.       }
  91.       return saltString.toString();
  92.     }
  93. }