blob: d3db2af5825d1d401c7bc282ff789cb7e6f00610 [file] [log] [blame]
/**
* 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.ranger.authorization.hive.udf;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
@Description(name = "mask_show_last_n",
value = "masks all but last n characters of the value",
extended = "Examples:\n "
+ " mask_show_last_n(ccn, 8)\n "
+ " mask_show_last_n(ccn, 8, 'x', 'x', 'x')\n "
+ "Arguments:\n "
+ " mask_show_last_n(value, charCount, upperChar, lowerChar, digitChar, otherChar, numberChar)\n "
+ " value - value to mask. Supported types: TINYINT, SMALLINT, INT, BIGINT, STRING, VARCHAR, CHAR\n "
+ " charCount - number of characters. Default value: 4\n "
+ " upperChar - character to replace upper-case characters with. Specify -1 to retain original character. Default value: 'X'\n "
+ " lowerChar - character to replace lower-case characters with. Specify -1 to retain original character. Default value: 'x'\n "
+ " digitChar - character to replace digit characters with. Specify -1 to retain original character. Default value: 'n'\n "
+ " otherChar - character to replace all other characters with. Specify -1 to retain original character. Default value: -1\n "
+ " numberChar - character to replace digits in a number with. Valid values: 0-9. Default value: '1'\n "
)
public class RangerUdfMaskShowLastN extends RangerBaseUdf {
public static final String UDF_NAME = "mask_show_last_n";
public RangerUdfMaskShowLastN() {
super(new MaskShowLastNTransformer(), UDF_NAME);
}
}
class MaskShowLastNTransformer extends MaskTransformer {
int charCount = 4;
public MaskShowLastNTransformer() {
super();
}
@Override
public void init(ObjectInspector[] arguments, int argsStartIdx) {
super.init(arguments, argsStartIdx + 1); // first argument is charCount, which is consumed in this method below
charCount = getIntArg(arguments, argsStartIdx, 4);
if(charCount < 0) {
charCount = 0;
}
}
@Override
String transform(final String value) {
if(value.length() <= charCount) {
return value;
}
final StringBuilder ret = new StringBuilder(value.length());
final int endIdx = value.length() - charCount;
for(int i = 0; i < endIdx; i++) {
ret.appendCodePoint(transformChar(value.charAt(i)));
}
for(int i = endIdx; i < value.length(); i++) {
ret.appendCodePoint(value.charAt(i));
}
return ret.toString();
}
@Override
Byte transform(final Byte value) {
byte val = value;
if(value < 0) {
val *= -1;
}
byte ret = 0;
int pos = 1;
for(int i = 0; val != 0; i++) {
if(i >= charCount) { // mask this digit
ret += maskedNumber * pos;
} else { //retain this digit
ret += (val % 10) * pos;
}
val /= 10;
pos *= 10;
}
if(value < 0) {
ret *= -1;
}
return ret;
}
@Override
Short transform(final Short value) {
short val = value;
if(value < 0) {
val *= -1;
}
short ret = 0;
int pos = 1;
for(int i = 0; val != 0; i++) {
if(i >= charCount) { // mask this digit
ret += maskedNumber * pos;
} else { // retain this digit
ret += (val % 10) * pos;
}
val /= 10;
pos *= 10;
}
if(value < 0) {
ret *= -1;
}
return ret;
}
@Override
Integer transform(final Integer value) {
int val = value;
if(value < 0) {
val *= -1;
}
int ret = 0;
int pos = 1;
for(int i = 0; val != 0; i++) {
if(i >= charCount) { // mask this digit
ret += maskedNumber * pos;
} else { // retain this digit
ret += (val % 10) * pos;
}
val /= 10;
pos *= 10;
}
if(value < 0) {
ret *= -1;
}
return ret;
}
@Override
Long transform(final Long value) {
long val = value;
if(value < 0) {
val *= -1;
}
long ret = 0;
long pos = 1;
for(int i = 0; val != 0; i++) {
if(i >= charCount) { // mask this digit
ret += (maskedNumber * pos);
} else { // retain this digit
ret += ((val % 10) * pos);
}
val /= 10;
pos *= 10;
}
if(value < 0) {
ret *= -1;
}
return ret;
}
}