Coverage Summary for Class: MacHashFunction (com.google.common.hash)

Class Method, % Line, %
MacHashFunction 0% (0/6) 0% (0/23)
MacHashFunction$MacHasher 0% (0/8) 0% (0/16)
Total 0% (0/14) 0% (0/39)


1 /* 2  * Copyright (C) 2015 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.hash; 16  17 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkState; 19  20 import com.google.errorprone.annotations.Immutable; 21 import java.nio.ByteBuffer; 22 import java.security.InvalidKeyException; 23 import java.security.Key; 24 import java.security.NoSuchAlgorithmException; 25 import javax.crypto.Mac; 26  27 /** 28  * {@link HashFunction} adapter for {@link Mac} instances. 29  * 30  * @author Kurt Alfred Kluever 31  */ 32 @Immutable 33 @ElementTypesAreNonnullByDefault 34 final class MacHashFunction extends AbstractHashFunction { 35  36  @SuppressWarnings("Immutable") // cloned before each use 37  private final Mac prototype; 38  39  @SuppressWarnings("Immutable") // keys are immutable, but not provably so 40  private final Key key; 41  42  private final String toString; 43  private final int bits; 44  private final boolean supportsClone; 45  46  MacHashFunction(String algorithmName, Key key, String toString) { 47  this.prototype = getMac(algorithmName, key); 48  this.key = checkNotNull(key); 49  this.toString = checkNotNull(toString); 50  this.bits = prototype.getMacLength() * Byte.SIZE; 51  this.supportsClone = supportsClone(prototype); 52  } 53  54  @Override 55  public int bits() { 56  return bits; 57  } 58  59  private static boolean supportsClone(Mac mac) { 60  try { 61  mac.clone(); 62  return true; 63  } catch (CloneNotSupportedException e) { 64  return false; 65  } 66  } 67  68  private static Mac getMac(String algorithmName, Key key) { 69  try { 70  Mac mac = Mac.getInstance(algorithmName); 71  mac.init(key); 72  return mac; 73  } catch (NoSuchAlgorithmException e) { 74  throw new IllegalStateException(e); 75  } catch (InvalidKeyException e) { 76  throw new IllegalArgumentException(e); 77  } 78  } 79  80  @Override 81  public Hasher newHasher() { 82  if (supportsClone) { 83  try { 84  return new MacHasher((Mac) prototype.clone()); 85  } catch (CloneNotSupportedException e) { 86  // falls through 87  } 88  } 89  return new MacHasher(getMac(prototype.getAlgorithm(), key)); 90  } 91  92  @Override 93  public String toString() { 94  return toString; 95  } 96  97  /** Hasher that updates a {@link Mac} (message authentication code). */ 98  private static final class MacHasher extends AbstractByteHasher { 99  private final Mac mac; 100  private boolean done; 101  102  private MacHasher(Mac mac) { 103  this.mac = mac; 104  } 105  106  @Override 107  protected void update(byte b) { 108  checkNotDone(); 109  mac.update(b); 110  } 111  112  @Override 113  protected void update(byte[] b) { 114  checkNotDone(); 115  mac.update(b); 116  } 117  118  @Override 119  protected void update(byte[] b, int off, int len) { 120  checkNotDone(); 121  mac.update(b, off, len); 122  } 123  124  @Override 125  protected void update(ByteBuffer bytes) { 126  checkNotDone(); 127  checkNotNull(bytes); 128  mac.update(bytes); 129  } 130  131  private void checkNotDone() { 132  checkState(!done, "Cannot re-use a Hasher after calling hash() on it"); 133  } 134  135  @Override 136  public HashCode hash() { 137  checkNotDone(); 138  done = true; 139  return HashCode.fromBytesNoCopy(mac.doFinal()); 140  } 141  } 142 }