/* * Copyright (c) 2017-2019 block.one all rights reserved. */ package one.block.eosiojava.utilities; import com.google.common.base.CharMatcher; import com.google.common.base.Strings; import org.bitcoinj.core.Sha256Hash; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.jetbrains.annotations.NotNull; /** * This class provides methods for transforming and formatting byte data to and from different * formats in use on the blockchain. */ public class ByteFormatter { private static final int BASE64_PADDING = 4; private static final char BASE64_PADDING_CHAR = '='; @NotNull private byte[] context; public ByteFormatter(@NotNull byte[] context) { this.context = context; } /** * Create and initialize a ByteFormatter from a Base64 encoded string. The Base64 string * will have its padding checked and adjusted if necessary. * * @param base64String - Base64 encoded string. * @return - Initialized ByteFormatter */ public static ByteFormatter createFromBase64(@NotNull String base64String) { // Base64 encoded strings must be an even multiple of 4 if they are handled with padding. // The strings that we get back from the blockchain in the JSON do not follow this // strictly so we have to adjust the string if necessary before decoding. The padding // character is '='. So we remove all existing padding characters and then pad the // string to the nearest multiple of 4. String trimmed = CharMatcher.is(BASE64_PADDING_CHAR).removeFrom(base64String); String padded = Strings.padEnd(trimmed, (trimmed.length() + BASE64_PADDING - 1) / BASE64_PADDING * BASE64_PADDING, BASE64_PADDING_CHAR); return new ByteFormatter(Base64.decode(padded)); } /** * Create and initialize a ByteFormatter from a hex encoded string. * * @param hexString - Hex encoded string. * @return - Initialized ByteFormatter */ public static ByteFormatter createFromHex(@NotNull String hexString) { byte[] data = Hex.decode(hexString); return new ByteFormatter(data); } /** * Convert the current ByteFormatter contents to a Hex encoded string and return it. * @return - Hex encoded string representation of the current formatter context. */ public String toHex() { return Hex.toHexString(this.context); } /** * Calculate the sha256 hash of the current ByteFormatter context and return it as a new * ByteFormatter. * * @return - New ByteFormatter containing the sha256 hash of the current one. */ public ByteFormatter sha256() { return new ByteFormatter(Sha256Hash.hash(this.context)); } }