Hex.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.binary;

  18. import java.nio.ByteBuffer;
  19. import java.nio.charset.Charset;
  20. import java.nio.charset.StandardCharsets;

  21. import org.apache.commons.codec.BinaryDecoder;
  22. import org.apache.commons.codec.BinaryEncoder;
  23. import org.apache.commons.codec.CharEncoding;
  24. import org.apache.commons.codec.DecoderException;
  25. import org.apache.commons.codec.EncoderException;

  26. /**
  27.  * Converts hexadecimal Strings. The Charset used for certain operation can be set, the default is set in
  28.  * {@link #DEFAULT_CHARSET_NAME}
  29.  *
  30.  * This class is thread-safe.
  31.  *
  32.  * @since 1.1
  33.  */
  34. public class Hex implements BinaryEncoder, BinaryDecoder {

  35.     /**
  36.      * Default charset is {@link StandardCharsets#UTF_8}.
  37.      *
  38.      * @since 1.7
  39.      */
  40.     public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

  41.     /**
  42.      * Default charset name is {@link CharEncoding#UTF_8}.
  43.      *
  44.      * @since 1.4
  45.      */
  46.     public static final String DEFAULT_CHARSET_NAME = CharEncoding.UTF_8;

  47.     /**
  48.      * Used to build output as hex.
  49.      */
  50.     private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

  51.     /**
  52.      * Used to build output as hex.
  53.      */
  54.     private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

  55.     /**
  56.      * Converts an array of characters representing hexadecimal values into an array of bytes of those same values. The
  57.      * returned array will be half the length of the passed array, as it takes two characters to represent any given
  58.      * byte. An exception is thrown if the passed char array has an odd number of elements.
  59.      *
  60.      * @param data An array of characters containing hexadecimal digits
  61.      * @return A byte array containing binary data decoded from the supplied char array.
  62.      * @throws DecoderException Thrown if an odd number of characters or illegal characters are supplied
  63.      */
  64.     public static byte[] decodeHex(final char[] data) throws DecoderException {
  65.         final byte[] out = new byte[data.length >> 1];
  66.         decodeHex(data, out, 0);
  67.         return out;
  68.     }

  69.     /**
  70.      * Converts an array of characters representing hexadecimal values into an array of bytes of those same values. The
  71.      * returned array will be half the length of the passed array, as it takes two characters to represent any given
  72.      * byte. An exception is thrown if the passed char array has an odd number of elements.
  73.      *
  74.      * @param data An array of characters containing hexadecimal digits
  75.      * @param out A byte array to contain the binary data decoded from the supplied char array.
  76.      * @param outOffset The position within {@code out} to start writing the decoded bytes.
  77.      * @return the number of bytes written to {@code out}.
  78.      * @throws DecoderException Thrown if an odd number of characters or illegal characters are supplied
  79.      * @since 1.15
  80.      */
  81.     public static int decodeHex(final char[] data, final byte[] out, final int outOffset) throws DecoderException {
  82.         final int len = data.length;
  83.         if ((len & 0x01) != 0) {
  84.             throw new DecoderException("Odd number of characters.");
  85.         }
  86.         final int outLen = len >> 1;
  87.         if (out.length - outOffset < outLen) {
  88.             throw new DecoderException("Output array is not large enough to accommodate decoded data.");
  89.         }
  90.         // two characters form the hex value.
  91.         for (int i = outOffset, j = 0; j < len; i++) {
  92.             int f = toDigit(data[j], j) << 4;
  93.             j++;
  94.             f |= toDigit(data[j], j);
  95.             j++;
  96.             out[i] = (byte) (f & 0xFF);
  97.         }
  98.         return outLen;
  99.     }

  100.     /**
  101.      * Converts a String representing hexadecimal values into an array of bytes of those same values. The returned array
  102.      * will be half the length of the passed String, as it takes two characters to represent any given byte. An
  103.      * exception is thrown if the passed String has an odd number of elements.
  104.      *
  105.      * @param data A String containing hexadecimal digits
  106.      * @return A byte array containing binary data decoded from the supplied char array.
  107.      * @throws DecoderException Thrown if an odd number of characters or illegal characters are supplied
  108.      * @since 1.11
  109.      */
  110.     public static byte[] decodeHex(final String data) throws DecoderException {
  111.         return decodeHex(data.toCharArray());
  112.     }

  113.     /**
  114.      * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
  115.      * The returned array will be double the length of the passed array, as it takes two characters to represent any
  116.      * given byte.
  117.      *
  118.      * @param data a byte[] to convert to hexadecimal characters
  119.      * @return A char[] containing lower-case hexadecimal characters
  120.      */
  121.     public static char[] encodeHex(final byte[] data) {
  122.         return encodeHex(data, true);
  123.     }

  124.     /**
  125.      * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
  126.      * The returned array will be double the length of the passed array, as it takes two characters to represent any
  127.      * given byte.
  128.      *
  129.      * @param data        a byte[] to convert to Hex characters
  130.      * @param toLowerCase {@code true} converts to lowercase, {@code false} to uppercase
  131.      * @return A char[] containing hexadecimal characters in the selected case
  132.      * @since 1.4
  133.      */
  134.     public static char[] encodeHex(final byte[] data, final boolean toLowerCase) {
  135.         return encodeHex(data, toAlphabet(toLowerCase));
  136.     }

  137.     /**
  138.      * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
  139.      * The returned array will be double the length of the passed array, as it takes two characters to represent any
  140.      * given byte.
  141.      *
  142.      * @param data     a byte[] to convert to hexadecimal characters
  143.      * @param toDigits the output alphabet (must contain at least 16 chars)
  144.      * @return A char[] containing the appropriate characters from the alphabet For best results, this should be either
  145.      *         upper- or lower-case hex.
  146.      * @since 1.4
  147.      */
  148.     protected static char[] encodeHex(final byte[] data, final char[] toDigits) {
  149.         final int dataLength = data.length;
  150.         return encodeHex(data, 0, dataLength, toDigits, new char[dataLength << 1], 0);
  151.     }

  152.     /**
  153.      * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
  154.      *
  155.      * @param data a byte[] to convert to hexadecimal characters
  156.      * @param dataOffset the position in {@code data} to start encoding from
  157.      * @param dataLen the number of bytes from {@code dataOffset} to encode
  158.      * @param toLowerCase {@code true} converts to lowercase, {@code false} to uppercase
  159.      * @return A char[] containing the appropriate characters from the alphabet For best results, this should be either
  160.      *         upper- or lower-case hex.
  161.      * @since 1.15
  162.      */
  163.     public static char[] encodeHex(final byte[] data, final int dataOffset, final int dataLen, final boolean toLowerCase) {
  164.         return encodeHex(data, dataOffset, dataLen, toAlphabet(toLowerCase), new char[dataLen << 1], 0);
  165.     }

  166.     /**
  167.      * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
  168.      *
  169.      * @param data a byte[] to convert to hexadecimal characters
  170.      * @param dataOffset the position in {@code data} to start encoding from
  171.      * @param dataLen the number of bytes from {@code dataOffset} to encode
  172.      * @param toLowerCase {@code true} converts to lowercase, {@code false} to uppercase
  173.      * @param out a char[] which will hold the resultant appropriate characters from the alphabet.
  174.      * @param outOffset the position within {@code out} at which to start writing the encoded characters.
  175.      * @since 1.15
  176.      */
  177.     public static void encodeHex(final byte[] data, final int dataOffset, final int dataLen, final boolean toLowerCase, final char[] out, final int outOffset) {
  178.         encodeHex(data, dataOffset, dataLen, toAlphabet(toLowerCase), out, outOffset);
  179.     }

  180.     /**
  181.      * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
  182.      *
  183.      * @param data a byte[] to convert to hexadecimal characters
  184.      * @param dataOffset the position in {@code data} to start encoding from
  185.      * @param dataLen the number of bytes from {@code dataOffset} to encode
  186.      * @param toDigits the output alphabet (must contain at least 16 chars)
  187.      * @param out a char[] which will hold the resultant appropriate characters from the alphabet.
  188.      * @param outOffset the position within {@code out} at which to start writing the encoded characters.
  189.      * @return the given {@code out}.
  190.      */
  191.     private static char[] encodeHex(final byte[] data, final int dataOffset, final int dataLen, final char[] toDigits, final char[] out, final int outOffset) {
  192.         // two characters form the hex value.
  193.         for (int i = dataOffset, j = outOffset; i < dataOffset + dataLen; i++) {
  194.             out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
  195.             out[j++] = toDigits[0x0F & data[i]];
  196.         }
  197.         return out;
  198.     }

  199.     /**
  200.      * Converts a byte buffer into an array of characters representing the hexadecimal values of each byte in order. The
  201.      * returned array will be double the length of the passed array, as it takes two characters to represent any given
  202.      * byte.
  203.      *
  204.      * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method
  205.      * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p>
  206.      *
  207.      * @param data a byte buffer to convert to hexadecimal characters
  208.      * @return A char[] containing lower-case hexadecimal characters
  209.      * @since 1.11
  210.      */
  211.     public static char[] encodeHex(final ByteBuffer data) {
  212.         return encodeHex(data, true);
  213.     }

  214.     /**
  215.      * Converts a byte buffer into an array of characters representing the hexadecimal values of each byte in order. The
  216.      * returned array will be double the length of the passed array, as it takes two characters to represent any given
  217.      * byte.
  218.      *
  219.      * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method
  220.      * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p>
  221.      *
  222.      * @param data        a byte buffer to convert to hexadecimal characters
  223.      * @param toLowerCase {@code true} converts to lowercase, {@code false} to uppercase
  224.      * @return A char[] containing hexadecimal characters in the selected case
  225.      * @since 1.11
  226.      */
  227.     public static char[] encodeHex(final ByteBuffer data, final boolean toLowerCase) {
  228.         return encodeHex(data, toAlphabet(toLowerCase));
  229.     }

  230.     /**
  231.      * Converts a byte buffer into an array of characters representing the hexadecimal values of each byte in order. The
  232.      * returned array will be double the length of the passed array, as it takes two characters to represent any given
  233.      * byte.
  234.      *
  235.      * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method
  236.      * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p>
  237.      *
  238.      * @param byteBuffer a byte buffer to convert to hexadecimal characters
  239.      * @param toDigits   the output alphabet (must be at least 16 characters)
  240.      * @return A char[] containing the appropriate characters from the alphabet For best results, this should be either
  241.      *         upper- or lower-case hex.
  242.      * @since 1.11
  243.      */
  244.     protected static char[] encodeHex(final ByteBuffer byteBuffer, final char[] toDigits) {
  245.         return encodeHex(toByteArray(byteBuffer), toDigits);
  246.     }

  247.     /**
  248.      * Converts an array of bytes into a String representing the hexadecimal values of each byte in order. The returned
  249.      * String will be double the length of the passed array, as it takes two characters to represent any given byte.
  250.      *
  251.      * @param data a byte[] to convert to hexadecimal characters
  252.      * @return A String containing lower-case hexadecimal characters
  253.      * @since 1.4
  254.      */
  255.     public static String encodeHexString(final byte[] data) {
  256.         return new String(encodeHex(data));
  257.     }

  258.     /**
  259.      * Converts an array of bytes into a String representing the hexadecimal values of each byte in order. The returned
  260.      * String will be double the length of the passed array, as it takes two characters to represent any given byte.
  261.      *
  262.      * @param data        a byte[] to convert to hexadecimal characters
  263.      * @param toLowerCase {@code true} converts to lowercase, {@code false} to uppercase
  264.      * @return A String containing lower-case hexadecimal characters
  265.      * @since 1.11
  266.      */
  267.     public static String encodeHexString(final byte[] data, final boolean toLowerCase) {
  268.         return new String(encodeHex(data, toLowerCase));
  269.     }

  270.     /**
  271.      * Converts a byte buffer into a String representing the hexadecimal values of each byte in order. The returned
  272.      * String will be double the length of the passed array, as it takes two characters to represent any given byte.
  273.      *
  274.      * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method
  275.      * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p>
  276.      *
  277.      * @param data a byte buffer to convert to hexadecimal characters
  278.      * @return A String containing lower-case hexadecimal characters
  279.      * @since 1.11
  280.      */
  281.     public static String encodeHexString(final ByteBuffer data) {
  282.         return new String(encodeHex(data));
  283.     }

  284.     /**
  285.      * Converts a byte buffer into a String representing the hexadecimal values of each byte in order. The returned
  286.      * String will be double the length of the passed array, as it takes two characters to represent any given byte.
  287.      *
  288.      * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method
  289.      * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p>
  290.      *
  291.      * @param data        a byte buffer to convert to hexadecimal characters
  292.      * @param toLowerCase {@code true} converts to lowercase, {@code false} to uppercase
  293.      * @return A String containing lower-case hexadecimal characters
  294.      * @since 1.11
  295.      */
  296.     public static String encodeHexString(final ByteBuffer data, final boolean toLowerCase) {
  297.         return new String(encodeHex(data, toLowerCase));
  298.     }

  299.     /**
  300.      * Converts a boolean to an alphabet.
  301.      *
  302.      * @param toLowerCase true for lowercase, false for uppercase.
  303.      * @return an alphabet.
  304.      */
  305.     private static char[] toAlphabet(final boolean toLowerCase) {
  306.         return toLowerCase ? DIGITS_LOWER : DIGITS_UPPER;
  307.     }

  308.     /**
  309.      * Convert the byte buffer to a byte array. All bytes identified by
  310.      * {@link ByteBuffer#remaining()} will be used.
  311.      *
  312.      * @param byteBuffer the byte buffer
  313.      * @return the byte[]
  314.      */
  315.     private static byte[] toByteArray(final ByteBuffer byteBuffer) {
  316.         final int remaining = byteBuffer.remaining();
  317.         // Use the underlying buffer if possible
  318.         if (byteBuffer.hasArray()) {
  319.             final byte[] byteArray = byteBuffer.array();
  320.             if (remaining == byteArray.length) {
  321.                 byteBuffer.position(remaining);
  322.                 return byteArray;
  323.             }
  324.         }
  325.         // Copy the bytes
  326.         final byte[] byteArray = new byte[remaining];
  327.         byteBuffer.get(byteArray);
  328.         return byteArray;
  329.     }

  330.     /**
  331.      * Converts a hexadecimal character to an integer.
  332.      *
  333.      * @param ch    A character to convert to an integer digit
  334.      * @param index The index of the character in the source
  335.      * @return An integer
  336.      * @throws DecoderException Thrown if ch is an illegal hexadecimal character
  337.      */
  338.     protected static int toDigit(final char ch, final int index) throws DecoderException {
  339.         final int digit = Character.digit(ch, 16);
  340.         if (digit == -1) {
  341.             throw new DecoderException("Illegal hexadecimal character " + ch + " at index " + index);
  342.         }
  343.         return digit;
  344.     }

  345.     private final Charset charset;

  346.     /**
  347.      * Creates a new codec with the default charset name {@link #DEFAULT_CHARSET}
  348.      */
  349.     public Hex() {
  350.         // use default encoding
  351.         this.charset = DEFAULT_CHARSET;
  352.     }

  353.     /**
  354.      * Creates a new codec with the given Charset.
  355.      *
  356.      * @param charset the charset.
  357.      * @since 1.7
  358.      */
  359.     public Hex(final Charset charset) {
  360.         this.charset = charset;
  361.     }

  362.     /**
  363.      * Creates a new codec with the given charset name.
  364.      *
  365.      * @param charsetName the charset name.
  366.      * @throws java.nio.charset.UnsupportedCharsetException If the named charset is unavailable
  367.      * @since 1.4
  368.      * @since 1.7 throws UnsupportedCharsetException if the named charset is unavailable
  369.      */
  370.     public Hex(final String charsetName) {
  371.         this(Charset.forName(charsetName));
  372.     }

  373.     /**
  374.      * Converts an array of character bytes representing hexadecimal values into an array of bytes of those same values.
  375.      * The returned array will be half the length of the passed array, as it takes two characters to represent any given
  376.      * byte. An exception is thrown if the passed char array has an odd number of elements.
  377.      *
  378.      * @param array An array of character bytes containing hexadecimal digits
  379.      * @return A byte array containing binary data decoded from the supplied byte array (representing characters).
  380.      * @throws DecoderException Thrown if an odd number of characters is supplied to this function
  381.      * @see #decodeHex(char[])
  382.      */
  383.     @Override
  384.     public byte[] decode(final byte[] array) throws DecoderException {
  385.         return decodeHex(new String(array, getCharset()).toCharArray());
  386.     }

  387.     /**
  388.      * Converts a buffer of character bytes representing hexadecimal values into an array of bytes of those same values.
  389.      * The returned array will be half the length of the passed array, as it takes two characters to represent any given
  390.      * byte. An exception is thrown if the passed char array has an odd number of elements.
  391.      *
  392.      * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method
  393.      * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p>
  394.      *
  395.      * @param buffer An array of character bytes containing hexadecimal digits
  396.      * @return A byte array containing binary data decoded from the supplied byte array (representing characters).
  397.      * @throws DecoderException Thrown if an odd number of characters is supplied to this function
  398.      * @see #decodeHex(char[])
  399.      * @since 1.11
  400.      */
  401.     public byte[] decode(final ByteBuffer buffer) throws DecoderException {
  402.         return decodeHex(new String(toByteArray(buffer), getCharset()).toCharArray());
  403.     }

  404.     /**
  405.      * Converts a String or an array of character bytes representing hexadecimal values into an array of bytes of those
  406.      * same values. The returned array will be half the length of the passed String or array, as it takes two characters
  407.      * to represent any given byte. An exception is thrown if the passed char array has an odd number of elements.
  408.      *
  409.      * @param object A String, ByteBuffer, byte[], or an array of character bytes containing hexadecimal digits
  410.      * @return A byte array containing binary data decoded from the supplied byte array (representing characters).
  411.      * @throws DecoderException Thrown if an odd number of characters is supplied to this function or the object is not
  412.      *                          a String or char[]
  413.      * @see #decodeHex(char[])
  414.      */
  415.     @Override
  416.     public Object decode(final Object object) throws DecoderException {
  417.         if (object instanceof String) {
  418.             return decode(((String) object).toCharArray());
  419.         }
  420.         if (object instanceof byte[]) {
  421.             return decode((byte[]) object);
  422.         }
  423.         if (object instanceof ByteBuffer) {
  424.             return decode((ByteBuffer) object);
  425.         }
  426.         try {
  427.             return decodeHex((char[]) object);
  428.         } catch (final ClassCastException e) {
  429.             throw new DecoderException(e.getMessage(), e);
  430.         }
  431.     }

  432.     /**
  433.      * Converts an array of bytes into an array of bytes for the characters representing the hexadecimal values of each
  434.      * byte in order. The returned array will be double the length of the passed array, as it takes two characters to
  435.      * represent any given byte.
  436.      * <p>
  437.      * The conversion from hexadecimal characters to the returned bytes is performed with the charset named by
  438.      * {@link #getCharset()}.
  439.      * </p>
  440.      *
  441.      * @param array a byte[] to convert to hexadecimal characters
  442.      * @return A byte[] containing the bytes of the lower-case hexadecimal characters
  443.      * @since 1.7 No longer throws IllegalStateException if the charsetName is invalid.
  444.      * @see #encodeHex(byte[])
  445.      */
  446.     @Override
  447.     public byte[] encode(final byte[] array) {
  448.         return encodeHexString(array).getBytes(getCharset());
  449.     }

  450.     /**
  451.      * Converts byte buffer into an array of bytes for the characters representing the hexadecimal values of each byte
  452.      * in order. The returned array will be double the length of the passed array, as it takes two characters to
  453.      * represent any given byte.
  454.      *
  455.      * <p>The conversion from hexadecimal characters to the returned bytes is performed with the charset named by
  456.      * {@link #getCharset()}.</p>
  457.      *
  458.      * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method
  459.      * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p>
  460.      *
  461.      * @param array a byte buffer to convert to hexadecimal characters
  462.      * @return A byte[] containing the bytes of the lower-case hexadecimal characters
  463.      * @see #encodeHex(byte[])
  464.      * @since 1.11
  465.      */
  466.     public byte[] encode(final ByteBuffer array) {
  467.         return encodeHexString(array).getBytes(getCharset());
  468.     }

  469.     /**
  470.      * Converts a String or an array of bytes into an array of characters representing the hexadecimal values of each
  471.      * byte in order. The returned array will be double the length of the passed String or array, as it takes two
  472.      * characters to represent any given byte.
  473.      * <p>
  474.      * The conversion from hexadecimal characters to bytes to be encoded to performed with the charset named by
  475.      * {@link #getCharset()}.
  476.      * </p>
  477.      *
  478.      * @param object a String, ByteBuffer, or byte[] to convert to hexadecimal characters
  479.      * @return A char[] containing lower-case hexadecimal characters
  480.      * @throws EncoderException Thrown if the given object is not a String or byte[]
  481.      * @see #encodeHex(byte[])
  482.      */
  483.     @Override
  484.     public Object encode(final Object object) throws EncoderException {
  485.         final byte[] byteArray;
  486.         if (object instanceof String) {
  487.             byteArray = ((String) object).getBytes(getCharset());
  488.         } else if (object instanceof ByteBuffer) {
  489.             byteArray = toByteArray((ByteBuffer) object);
  490.         } else {
  491.             try {
  492.                 byteArray = (byte[]) object;
  493.             } catch (final ClassCastException e) {
  494.                 throw new EncoderException(e.getMessage(), e);
  495.             }
  496.         }
  497.         return encodeHex(byteArray);
  498.     }

  499.     /**
  500.      * Gets the charset.
  501.      *
  502.      * @return the charset.
  503.      * @since 1.7
  504.      */
  505.     public Charset getCharset() {
  506.         return this.charset;
  507.     }

  508.     /**
  509.      * Gets the charset name.
  510.      *
  511.      * @return the charset name.
  512.      * @since 1.4
  513.      */
  514.     public String getCharsetName() {
  515.         return this.charset.name();
  516.     }

  517.     /**
  518.      * Returns a string representation of the object, which includes the charset name.
  519.      *
  520.      * @return a string representation of the object.
  521.      */
  522.     @Override
  523.     public String toString() {
  524.         return super.toString() + "[charsetName=" + this.charset + "]";
  525.     }
  526. }