I dont understand this line of code (hexchar_to_int(str[i]) << 4) | hexchar_to_int(str[i+1])) . Can someone explains me - c++17

I reviewed these lines of codes which used to convert string to binary, but i cant understand what this
line of code is doing (hexchar_to_int(str[i]) << 4) | hexchar_to_int(str[i+1]), i am frustrated
with this bit manipulation here, 8 bit of unsigned int used and we shifted left to get the least 4
significant bits. But i don't know the purpose of doing so.
unsigned char hexchar_to_int(char const ch)
{
if (ch >= '0' && ch <= '9') return ch - '0';
if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
throw std::invalid_argument("Invalid hexadecimal character");
}
std::vector<unsigned char> hexstr_to_bytes(std::string_view str)
{
std::vector<unsigned char> result;
for (size_t i = 0; i < str.size(); i += 2)
{
result.push_back((hexchar_to_int(str[i]) << 4) | hexchar_to_int(str[i+1]));
}
return result;
}

<<4 is *2^4 or *16, shifting left, not right.
The | is a simple addition of the 2 hexa characters at their correct place.
See 0xab = 10*16 + 11 = 171

Related

python Z3 how to use if without else

I try to use z3 do some easy math, condition is if without else.
........................................
for (i = 0; i <= 15; ++i)
{
if (s1[i] > 64 && s1[i] <= 90)
s1[i] = (s1[i] - 51) % 26 + 65;
if (s1[i] > 96 && s1[i] <= 122)
s1[i] = (s1[i] - 79) % 26 + 97;
}
for (i = 0; i <= 15; ++i)
{
result = key[i];
if (s1[i] != result)
return result;
}
from z3 import *
key = list(b"Qsw3sj_lz4_Ujw#l")
s1 = [BitVec('s1_%d' % i, 8) for i in range(len(key))]
s = Solver()
for i, n in enumerate(key):
con1 = If(Or(64 < s1[i], s1[i] <= 90), (s1[i] - 51) % 26 + 65 == key[i])
con2 = If(Or(96 < s1[i], s1[i] <= 122), (s1[i] - 79) % 26 + 97 == key[i])
s.add(con1)
s.add(con2)
print(s.check())
print(s.model())
Got error. TypeError: If() missing 1 required positional argument: 'c'
If takes three arguments; (1) condition, (2) then result, and (3) else result. You've only provided two. You can substitute True if you don't care about the else case constraint:
con1 = If(Or(64 < s1[i], s1[i] <= 90), (s1[i] - 51) % 26 + 65 == key[i], True)
and similarly for con2.
Note that there's no such thing as an If without else in z3.
While this will fix your "syntax" error, it won't fix the mistake you're making in your model; if any, of course. (As stated, your conditions are unsat, which I presume wasn't what you were expecting.) You should really consider what how the program changes (or doesn't change) when the condition is false, and instead of constraints like this, you should model how the variables themselves change after putting them into SSA (single-static assignment form.)

C to Lua conversion - weird result

I have a C function that I want to convert to LUA but I'm getting strange results out of Lua:
unsigned short crc16(const char* pstrCurrent, int iCount)
{
unsigned short wCRC = 0;
int iIndex = 0;
while(--iCount >= 0)
{
wCRC = wCRC ^ ((int)(*pstrCurrent++) << 8);
printf ("WCRC = %u\n", wCRC);
}
return (wCRC & 0xFFFF);
}
and here is how I started the Lua:
local function crc16(keyCurrent, byteCount)
wCRC = 0
byteIndex = 1
local crcInput = {}
while byteCount > 0 do
print ("BYTE COUNT= " .. byteCount)
wCRC=bit32.bxor(wCRC, bit32.lshift(keyCurrent[byteIndex], 8))
print ( "WCRC = " .. wCRC )
byteCount = byteCount-1
byteIndex = byteIndex+1
end
end
Yes, I know the C function is incomplete, I just want to compare what's causing issues.
The prints of the WCRC is C and Lua print completely different numbers for the same input.
Is my Lua conversion incorrect? It is my second or third time using Lua so not quite sure what I'm doing wrong.
***************** UPDATE ********************
So here is the full C and LUA and a quick little test code:
unsigned short crc16(const char* pstrCurrent, int iCount)
{
unsigned short wCRC = 0;
int iIndex = 0;
// Perform the following for each character in the buffer
while(--iCount >= 0)
{
// Get the byte information for the calculation and
// advance the pointer
wCRC = wCRC ^ ((int)(*pstrCurrent++) << 8);
for(iIndex = 0; iIndex < 8; ++iIndex)
{
if(wCRC & 0x8000)
{
wCRC = (wCRC << 1) ^ 0x1021;
}
else
{
wCRC = wCRC << 1;
}
}
}
return (wCRC & 0xFFFF);
}
and the LUA conversion:
function crc16 (keyCurrent, iCount)
wCRC = 0
byteIndex = 1
iIndex = 0
local crcInput = {}
while iCount >= 1 do
wCRC = bit32.bxor (wCRC, bit32.lshift(keyCurrent[byteIndex], 8))
for iIndex=0,8 do
if (bit32.band (wCRC, 0x8000) ~= nil ) then
wCRC = bit32.bxor (bit32.lshift (wCRC, 1), 0x1021)
else
wCRC = bit32.lshift (wCRC, 1)
end
end
iCount = iCount-1
byteIndex = byteIndex+1
end
return (bit32.band (wCRC, 0xFFFF))
end
local dKey = {}
dKey = {8, 210, 59, 0, 18, 166, 254, 117}
print ( "CRC = " .. crc16 (dKey ,8) )
In C, for the same array I get: CRC16 = 567
In LUA, I get: CRC = 61471
Can someone tell me what I'm doing wrong?
Thanks
It seems they yield the same results:
pure-C
WCRC = 18432
WCRC = 11520
WCRC = 16640
WCRC = 11520
pure-Lua
BYTE COUNT= 4
WCRC = 18432
BYTE COUNT= 3
WCRC = 11520
BYTE COUNT= 2
WCRC = 16640
BYTE COUNT= 1
WCRC = 11520
ASCII convertor:
What do you mean?
There's mistakes in altered Lua sample.
1. bit32.band() returns number. Number 0 not equals to 'nil', that's totally different type. You're trying to compare number with nil, and that check will fail always.2. for iIndex=0,8 do iterates 9 times, including final index 8.

How to loop over array in Z3Py

As part of a reverse engineering exercise, I'm trying to write a Z3 solver to find a username and password that satisfy the program below. This is especially tough because the z3py tutorial that everyone refers to (rise4fun) is down.
#include <iostream>
#include <string>
using namespace std;
int main() {
string name, pass;
cout << "Name: ";
cin >> name;
cout << "Pass: ";
cin >> pass;
int sum = 0;
for (size_t i = 0; i < name.size(); i++) {
char c = name[i];
if (c < 'A') {
cout << "Lose: char is less than A" << endl;
return 1;
}
if (c > 'Z') {
sum += c - 32;
} else {
sum += c;
}
}
int r1 = 0x5678 ^ sum;
int r2 = 0;
for (size_t i = 0; i < pass.size(); i++) {
char c = pass[i];
c -= 48;
r2 *= 10;
r2 += c;
}
r2 ^= 0x1234;
cout << "r1: " << r1 << endl;
cout << "r2: " << r2 << endl;
if (r1 == r2) {
cout << "Win" << endl;
} else {
cout << "Lose: r1 and r2 don't match" << endl;
}
}
I got that code from the assembly of a binary, and while it may be wrong I want to focus on writing the solver. I'm starting with the first part, just calculating r1, and this is what I have:
from z3 import *
s = Solver()
sum = Int('sum')
name = Array('name', IntSort(), IntSort())
for c in name:
s.add(c < 65)
if c > 90:
sum += c - 32
else:
sum += c
r1 = Xor(sum, 0x5678)
print s.check()
print s.model()
All I'm asserting is that there are no letters less than 'A' in the array, so I expect to get back an array of any size that has numbers greater than 65.
Obviously this is completely wrong, mainly because it infinite loops. Also, I'm not sure I'm calculating sum correctly, because I don't know if it's initialized to 0. Could someone help figure out how to get this first loop working?
EDIT: I was able to get a z3 script that is close to the C++ code shown above:
from z3 import *
s = Solver()
sum = 0
name = Array('name', BitVecSort(32), BitVecSort(32))
i = Int('i')
for i in xrange(0, 1):
s.add(name[i] >= 65)
s.add(name[i] < 127)
if name[i] > 90:
sum += name[i] - 32
else:
sum += name[i]
r1 = sum ^ 0x5678
passwd = Array('passwd', BitVecSort(32), BitVecSort(32))
r2 = 0
for i in xrange(0, 5):
s.add(passwd[i] < 127)
s.add(passwd[i] >= 48)
c = passwd[i] - 48
r2 *= 10
r2 += c
r2 ^= 0x1234
s.add(r1 == r2)
print s.check()
print s.model()
This code was able to give me a correct username and password. However, I hardcoded the lengths of one for the username and five for the password. How would I change the script so I wouldn't have to hard code the lengths? And how would I generate a different solution each time I run the program?
Arrays in Z3 do not necessarily have any bounds. In this case the index-sort is Int, which means unbounded integers (not machine integers). Consequently, for c in name will run forever because it enumerates name[0], name[1], name[2], ...
It seems that you actually have a bound in the original program (name.size()), so it would suffice to enumerate up to that limit. Otherwise you might need a quantifier, e.g., \forall x of Int sort . name[x] < 65. This comes with all the warnings about quantifiers, of course (see e.g., the Z3 Guide)
Suppose the length is to be determined. Here is what I think you could do:
length = Int('length')
x = Int('x')
s.add(ForAll(x,Implies(And(x>=0,x<length),And(passwd[x] < 127,passwd[x] >=48))))

PNG validation on iOS

Writing a mapping application on iOS, making use of OpenStreetMap tiles.
Map tile images are downloaded asynchronously and stored in a dictionary, or persisted in a SQLite DB.
Occasionally, for whatever reason, while attempting to render a map tile image, I get the following error:
ImageIO: <ERROR> PNGinvalid distance too far back
This causes nasty black squares to appear over my map.
This is the piece of code in which this occurs:
NSData *imageData = [TileDownloader RetrieveDataAtTileX:(int)tilex Y:(int)tiley Zoom:(int)zoomLevel];
if (imageData != nil) {
NSLog(#"Obtained image data\n");
UIImage *img = [[UIImage imageWithData:imageData] retain];
// Perform the image render on the current UI context.
// ERROR OCCURS BETWEEN PUSH AND POP
UIGraphicsPushContext(context);
[img drawInRect:[self rectForMapRect:mapRect] blendMode:kCGBlendModeNormal alpha:1.0f];
UIGraphicsPopContext();
[img release];
}
Now, what I'm looking for is a way to ensure a png is valid before attempting to render it to my map.
Edit: The system also occasionally throws this error:
ImageIO: <ERROR> PNGIDAT: CRC error
I found this in other question and put together what solved the issue for me. Hope you find this helpful.
The PNG format has several built in checks. Each "chunk" has a CRC32 check, but to check that you'd need to read the full file.
A more basic check (not foolproof, of course) would be to read the start and ending of the file.
The first 8 bytes should always be the following (decimal) values { 137, 80, 78, 71, 13, 10, 26, 10 } (ref). In particular, the bytes second-to-fourth correspond to the ASCII string "PNG".
In hexadecimal:
89 50 4e 47 0d 0a 1a 0a
.. P N G ...........
You can also check the last 12 bytes of the file (IEND chunk). The middle 4 bytes should correspond to the ASCII string "IEND". More specifically the last 12 bytes should be (in hexa):
00 00 00 00 49 45 4e 44 ae 42 60 82
........... I E N D ...........
(Strictly speaking, it's not really obligatory for a PNG file to end with those 12 bytes, the IEND chunk itself signals the end of the PNG stream and so a file could in principle have extra trailing bytes which would be ignored by the PNG reader. In practice, this is extremely improbable).
Here is an implementation:
- (BOOL)dataIsValidPNG:(NSData *)data
{
if (!data || data.length < 12)
{
return NO;
}
NSInteger totalBytes = data.length;
const char *bytes = (const char *)[data bytes];
return (bytes[0] == (char)0x89 && // PNG
bytes[1] == (char)0x50 &&
bytes[2] == (char)0x4e &&
bytes[3] == (char)0x47 &&
bytes[4] == (char)0x0d &&
bytes[5] == (char)0x0a &&
bytes[6] == (char)0x1a &&
bytes[7] == (char)0x0a &&
bytes[totalBytes - 12] == (char)0x00 && // IEND
bytes[totalBytes - 11] == (char)0x00 &&
bytes[totalBytes - 10] == (char)0x00 &&
bytes[totalBytes - 9] == (char)0x00 &&
bytes[totalBytes - 8] == (char)0x49 &&
bytes[totalBytes - 7] == (char)0x45 &&
bytes[totalBytes - 6] == (char)0x4e &&
bytes[totalBytes - 5] == (char)0x44 &&
bytes[totalBytes - 4] == (char)0xae &&
bytes[totalBytes - 3] == (char)0x42 &&
bytes[totalBytes - 2] == (char)0x60 &&
bytes[totalBytes - 1] == (char)0x82);
}
I know this is a super old thread, but I was looking around for an NSData extension that actually validated the crc32's in the PNG data chunks. Having not found one, I adapted one from some other source.
This will actually flag bad PNG CRC's, which isn't done (shockingly) by most image libraries
static const unsigned int datacrc32_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
0x2d02ef8d
};
unsigned int
datacrc32 (unsigned int crc, unsigned char *buf, int len)
{
unsigned char *end;
crc = ~crc;
for (end = buf + len; buf < end; ++buf)
crc = datacrc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
return ~crc;
}
-(BOOL)isCRCValidPNG {
char chnk [5];
int l = 0;
int size = (int)[self length];
unsigned int crc = 0;
unsigned char c;
unsigned int csum = 0;
unsigned char b;
unsigned char *tileBytes = (unsigned char *)[self bytes];
if (self.length > 8){
const unsigned char pngHeaderBytes[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
for (int i = 0 ; i < 8 ; ++i){
if (tileBytes[i] != pngHeaderBytes[i])
return NO;
}
}
// process chunks
int bytePtr = 8;
strcpy (chnk, "");
do
{
// get chunk size
if (bytePtr+4 > size)
return NO;
l = 0;
for (int i = 0; i < 4; i++)
{
l = (l << 8) + tileBytes[bytePtr++];
}
printf("l is %08x",l);
// get chunk name
crc = 0;
strcpy (chnk, "");
if (bytePtr+4 > size)
return NO;
for (int i = 0; i < 4; i++)
{
c = tileBytes[bytePtr++];
crc = datacrc32 (crc, &c, 1);
chnk[i] = (char) c;
}
chnk[4] = '\0';
printf ("%s (%3d )", chnk, l);
// chunk data
if (bytePtr+l > size)
return NO;
for (int i = 0; i < l; i++)
{
c = tileBytes[bytePtr++];
crc = datacrc32 (crc, &c, 1);
}
// checksum
csum = 0;
if (bytePtr+4 > size)
return NO;
for (int i = 0; i < 4; i++)
{
c = tileBytes[bytePtr++];
csum = (csum << 8) + (int) c;
b = (unsigned char) ((crc >> 8 * (3 - i)) & 0xFF);
// printf ("b = %02x\n", b);
}
if (crc == csum)
NSLog(#"Chunk %s validated",chnk);
else
NSLog(#"chunk %s invalid ",chnk);
if (crc != csum)
return NO;
}
while (strcmp (chnk, "IEND") != 0);
return YES;
}
Switched from my own Asynchronous Download Queue Manager to the All Seeing I implementation. Problem became a moot point.
The Swift Version
func checkPNGImageDataFormat(_ imageData:Data) -> Bool
{
//More expensive since it has to go through entire data
//Check entire header magic number and IEND trailer in PNG data
var status:Bool = true
if(imageData.count < 12)
{
return false
}
let totalBytes = imageData.count
let bytes = imageData.withUnsafeBytes {
[UInt8](UnsafeBufferPointer(start: $0, count: totalBytes))
}
let header:Bool = bytes[0] == 0x89 && bytes[1] == 0x50 && bytes[2] == 0x4e && bytes[3] == 0x47 && bytes[4] == 0x0d && bytes[5] == 0x0a && bytes[6] == 0x1a && bytes[7] == 0x0a
let iend:Bool = bytes[totalBytes - 12] == 0x00 && bytes[totalBytes - 11] == 0x00 && bytes[totalBytes - 10] == 0x00 && bytes[totalBytes - 9] == 0x00 && bytes[totalBytes - 8] == 0x49 && bytes[totalBytes - 7] == 0x45 && bytes[totalBytes - 6] == 0x4e && bytes[totalBytes - 5] == 0x44 && bytes[totalBytes - 4] == 0xae && bytes[totalBytes - 3] == 0x42 && bytes[totalBytes - 2] == 0x60 && bytes[totalBytes - 1] == 0x82
status = header && iend
return status
}

Url contain special charectors

I am trying to establish a https connection but my URL contains some special characters, so creating the connection is throwing an Exception. How do I avoid this problem?
You can encode like this,
public class URLUTF8Encoder
{
final static String[] hex = {
"%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07",
"%08", "%09", "%0a", "%0b", "%0c", "%0d", "%0e", "%0f",
"%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",
"%18", "%19", "%1a", "%1b", "%1c", "%1d", "%1e", "%1f",
"%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27",
"%28", "%29", "%2a", "%2b", "%2c", "%2d", "%2e", "%2f",
"%30", "%31", "%32", "%33", "%34", "%35", "%36", "%37",
"%38", "%39", "%3a", "%3b", "%3c", "%3d", "%3e", "%3f",
"%40", "%41", "%42", "%43", "%44", "%45", "%46", "%47",
"%48", "%49", "%4a", "%4b", "%4c", "%4d", "%4e", "%4f",
"%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57",
"%58", "%59", "%5a", "%5b", "%5c", "%5d", "%5e", "%5f",
"%60", "%61", "%62", "%63", "%64", "%65", "%66", "%67",
"%68", "%69", "%6a", "%6b", "%6c", "%6d", "%6e", "%6f",
"%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77",
"%78", "%79", "%7a", "%7b", "%7c", "%7d", "%7e", "%7f",
"%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87",
"%88", "%89", "%8a", "%8b", "%8c", "%8d", "%8e", "%8f",
"%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97",
"%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f",
"%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
"%a8", "%a9", "%aa", "%ab", "%ac", "%ad", "%ae", "%af",
"%b0", "%b1", "%b2", "%b3", "%b4", "%b5", "%b6", "%b7",
"%b8", "%b9", "%ba", "%bb", "%bc", "%bd", "%be", "%bf",
"%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7",
"%c8", "%c9", "%ca", "%cb", "%cc", "%cd", "%ce", "%cf",
"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
"%d8", "%d9", "%da", "%db", "%dc", "%dd", "%de", "%df",
"%e0", "%e1", "%e2", "%e3", "%e4", "%e5", "%e6", "%e7",
"%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee", "%ef",
"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
"%f8", "%f9", "%fa", "%fb", "%fc", "%fd", "%fe", "%ff"
};
public static String encode(String s)
{
StringBuffer sbuf = new StringBuffer();
int len = s.length();
for (int i = 0; i < len; i++) {
int ch = s.charAt(i);
if ('A' <= ch && ch <= 'Z') { // 'A'..'Z'
sbuf.append((char)ch);
} else if ('a' <= ch && ch <= 'z') { // 'a'..'z'
sbuf.append((char)ch);
} else if ('0' <= ch && ch <= '9') { // '0'..'9'
sbuf.append((char)ch);
} else if (ch == ' ') { // space
sbuf.append('+');
} else if (ch == '-' || ch == '_' // unreserved
|| ch == '.' || ch == '!'
|| ch == '~' || ch == '*'
|| ch == '\'' || ch == '('
|| ch == ')') {
sbuf.append((char)ch);
} else if (ch <= 0x007f) { // other ASCII
sbuf.append(hex[ch]);
} else if (ch <= 0x07FF) { // non-ASCII <= 0x7FF
sbuf.append(hex[0xc0 | (ch >> 6)]);
sbuf.append(hex[0x80 | (ch & 0x3F)]);
} else { // 0x7FF < ch <= 0xFFFF
sbuf.append(hex[0xe0 | (ch >> 12)]);
sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]);
sbuf.append(hex[0x80 | (ch & 0x3F)]);
}
}
return sbuf.toString();
}
}
referenced By
HTTP://WWW.W3.ORG/INTERNATIONAL/URLUTF8ENCODER.JAVA
There are several solutions for this. Pick the one you like most.

Resources