/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.hadoop.hive.ql.udf; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; /** * UDFUnhex. * */ @Description(name = "unhex", value = "_FUNC_(str) - Converts hexadecimal argument to binary", extended = "Performs the inverse operation of HEX(str). That is, it interprets\n" + "each pair of hexadecimal digits in the argument as a number and\n" + "converts it to the byte representation of the number. The\n" + "resulting characters are returned as a binary string.\n\n" + "Example:\n" + "> SELECT DECODE(UNHEX('4D7953514C'), 'UTF-8') from src limit 1;\n" + "'MySQL'\n\n" + "The characters in the argument string must be legal hexadecimal\n" + "digits: '0' .. '9', 'A' .. 'F', 'a' .. 'f'. If UNHEX() encounters\n" + "any nonhexadecimal digits in the argument, it returns NULL. Also,\n" + "if there are an odd number of characters a leading 0 is appended.") public class UDFUnhex extends UDF { /** * Convert every two hex digits in s into. * */ public byte[] evaluate(Text s) { if (s == null) { return null; } // append a leading 0 if needed String str; if (s.getLength() % 2 == 1) { str = "0" + s.toString(); } else { str = s.toString(); } byte[] result = new byte[str.length() / 2]; for (int i = 0; i < str.length(); i += 2) { try { result[i / 2] = ((byte) Integer.parseInt(str.substring(i, i + 2), 16)); } catch (NumberFormatException e) { // invalid character present, return null return null; } } return result; } }