001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.util; 018 019import org.apache.wicket.util.string.PrependingStringBuffer; 020 021/** 022 * Encodes long values into the specified alphabet. Encoding is useful when long values need to be 023 * represented in their string form and shorter values are preferred; by using alphabets of length 024 * greater than ten shorter values can be obtained. For example, to encode values into their 025 * hexadecimal representations the {@code 0123456789ABCDEF-} can be used. Long values can be 026 * shortened even further by using longer alphabets. The last character in the alphabet is used as 027 * the negative sign. 028 * 029 * @author igor 030 */ 031public class LongEncoder 032{ 033 /** 034 * default alphabet that should be safe to use in most circumstances, while still providing good 035 * shortening of long values 036 */ 037 public static final String DEFAULT = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 038 039 private LongEncoder() 040 { 041 } 042 043 /** 044 * Encodes the value into the default alphabet: {@value #DEFAULT} 045 * 046 * @param value 047 * @return encoded value 048 */ 049 public static String encode(final long value) 050 { 051 return encode(value, DEFAULT); 052 } 053 054 /** 055 * Decodes value using the default alphabet: {@value #DEFAULT} 056 * 057 * @param value 058 * @return decoded value 059 */ 060 public static long decode(final String value) 061 { 062 return decode(value, DEFAULT); 063 } 064 065 /** 066 * Encodes value into the specified alphabet 067 * 068 * @param value 069 * @param alphabet 070 * @return encoded value 071 */ 072 public static String encode(long value, final String alphabet) 073 { 074 final int len = alphabet.length() - 1; 075 PrependingStringBuffer buff = new PrependingStringBuffer(); 076 final boolean negative = value < 0; 077 if (negative) 078 { 079 value = -value; 080 } 081 do 082 { 083 int mod = (int)(value % len); 084 buff.prepend(alphabet.charAt(mod)); 085 value = value / len; 086 } 087 while (value > 0); 088 if (negative) 089 { 090 buff.prepend(alphabet.charAt(len)); 091 } 092 return buff.toString(); 093 } 094 095 /** 096 * Decodes value using the specified alphabet 097 * 098 * @param value 099 * @param alphabet 100 * @return decoded value 101 */ 102 public static long decode(final String value, final String alphabet) 103 { 104 final int factor = alphabet.length() - 1; 105 final boolean negative = alphabet.charAt(factor) == value.charAt(0); 106 long num = 0; 107 for (int i = (negative) ? 1 : 0, len = value.length(); i < len; i++) 108 { 109 num = num * factor + alphabet.indexOf(value.charAt(i)); 110 } 111 if (negative) 112 { 113 num = -num; 114 } 115 return num; 116 } 117}