1 25 package org.archive.util; 26 27 36 public class Base32 { 37 private static final String base32Chars = 38 "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 39 private static final int[] base32Lookup = 40 { 0xFF,0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06, 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06, 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF }; 51 52 59 static public String encode(final byte[] bytes) { 60 int i = 0, index = 0, digit = 0; 61 int currByte, nextByte; 62 StringBuffer base32 = new StringBuffer ((bytes.length + 7) * 8 / 5); 63 64 while (i < bytes.length) { 65 currByte = (bytes[i] >= 0) ? bytes[i] : (bytes[i] + 256); 67 68 if (index > 3) { 69 if ((i + 1) < bytes.length) { 70 nextByte = 71 (bytes[i + 1] >= 0) ? bytes[i + 1] : (bytes[i + 1] + 256); 72 } else { 73 nextByte = 0; 74 } 75 76 digit = currByte & (0xFF >> index); 77 index = (index + 5) % 8; 78 digit <<= index; 79 digit |= nextByte >> (8 - index); 80 i++; 81 } else { 82 digit = (currByte >> (8 - (index + 5))) & 0x1F; 83 index = (index + 5) % 8; 84 if (index == 0) 85 i++; 86 } 87 base32.append(base32Chars.charAt(digit)); 88 } 89 90 return base32.toString(); 91 } 92 93 99 static public byte[] decode(final String base32) { 100 int i, index, lookup, offset, digit; 101 byte[] bytes = new byte[base32.length() * 5 / 8]; 102 103 for (i = 0, index = 0, offset = 0; i < base32.length(); i++) { 104 lookup = base32.charAt(i) - '0'; 105 106 107 if (lookup < 0 || lookup >= base32Lookup.length) { 108 continue; 109 } 110 111 digit = base32Lookup[lookup]; 112 113 114 if (digit == 0xFF) { 115 continue; 116 } 117 118 if (index <= 3) { 119 index = (index + 5) % 8; 120 if (index == 0) { 121 bytes[offset] |= digit; 122 offset++; 123 if (offset >= bytes.length) 124 break; 125 } else { 126 bytes[offset] |= digit << (8 - index); 127 } 128 } else { 129 index = (index + 5) % 8; 130 bytes[offset] |= (digit >>> index); 131 offset++; 132 133 if (offset >= bytes.length) { 134 break; 135 } 136 bytes[offset] |= digit << (8 - index); 137 } 138 } 139 return bytes; 140 } 141 142 147 static public void main(String [] args) { 148 if (args.length == 0) { 149 System.out.println("Supply a Base32-encoded argument."); 150 return; 151 } 152 System.out.println(" Original: " + args[0]); 153 byte[] decoded = Base32.decode(args[0]); 154 System.out.print(" Hex: "); 155 for (int i = 0; i < decoded.length; i++) { 156 int b = decoded[i]; 157 if (b < 0) { 158 b += 256; 159 } 160 System.out.print((Integer.toHexString(b + 256)).substring(1)); 161 } 162 System.out.println(); 163 System.out.println("Reencoded: " + Base32.encode(decoded)); 164 } 165 } 166 | Popular Tags |