Solved

The worst method I wrote in my programming life :-(

Posted on 2004-08-25
43
286 Views
Last Modified: 2012-05-05
 private String replaceSpecial(String main, String special) {
    special = special.trim();
    for (int i = 0; i < special.length(); i++) {

      char c = special.charAt(i);
      switch (c) {
        case ':': {
          main = main.replaceAll(c + "", "%3a");
          break;
        }
        case '?': {
          main = main.replaceAll("\\?", "%3f");
          break;
        }
        case '*': {
          main = main.replaceAll("\\*", "%2a");
          break;
        }
        case '"': {
          main = main.replaceAll("\"", "%22");
          break;
        }
        case '<': {
          main = main.replaceAll("\\<", "%3c");
          break;
        }
        case '>': {
          main = main.replaceAll("\\>", "%3e");
          break;
        }
        case '\\': {
          main = main.replaceAll("\\\\", "_xf8fe_");
          //main=java.net.URLDecoder.decode(main);
          break;
        }
        case 47: {

          main = main.replaceAll("\\/", "%2f");

          break;
        }
        case '|': {

          main = main.replaceAll("\\|", "%7c");

          break;
        }
        case '&': {

          main = main.replaceAll("&", "%26");

          break;
        }
        case '#': {

          main = main.replaceAll("#", "%23");

          break;
        }
        /*case '^': {
                main = main.replaceAll("^", "%5e");

                break;
              }*/

        /*  case '=' :
                           {

                main= main.replaceAll(" ","+");
                  main= main.replaceAll("%20","+");

                break;
                           }*/

      }
    }

    return main;
  }

:-(
0
Comment
Question by:sudhakar_koundinya
  • 20
  • 8
  • 7
  • +5
43 Comments
 
LVL 92

Accepted Solution

by:
objects earned 150 total points
ID: 11900009
store all your replacements in a Map, then you can replace the entire switch with a loop over all the elements of the map.
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900021
I do not understand Why URLEncoder.encode is not working always for me. That is the reason, I am trying to write my own method
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900031
>> store all your replacements in a Map, then you can replace the entire switch with a loop over all the elements of the loop

I thought the same but x=x.replaceAll(string,string1) is worst case here. right?

So how efficiently I can modify that
0
 
LVL 35

Expert Comment

by:girionis
ID: 11900042
URLEncoder should work. Why do you say it does not?
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900045
BTW,

can u have a glance on this thread too http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_21106407.html

thanks
Sudha
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11900139
public class HtmlEncoder
{
  private static final String[] htmlCode = new String[ 256 ] ;
  static
  {
    for( int i = 0 ; i < 10 ; i++ )
    {
      htmlCode[ i ] = "&#00" + i + ";" ;
    }

    for( int i = 10 ; i < 32 ; i++ )
    {
      htmlCode[ i ] = "&#0" + i + ";" ;
    }

    for( int i = 32 ; i < 128 ; i++ )
    {
      htmlCode[ i ] = String.valueOf( ( char )i ) ;
    }

    // Special characters
    htmlCode[ '\t' ] = "\t" ;
    htmlCode[ '\n' ] = "<br>\n" ;
    htmlCode[ '\r' ] = "" ;
    htmlCode[ '\"' ] = "&quot;" ; // double quote
    htmlCode[ '&' ] = "&amp;" ; // ampersand
    htmlCode[ '<' ] = "&lt;" ; // lower than
    htmlCode[ '>' ] = "&gt;" ; // greater than

    for( int i = 128 ; i < 256 ; i++ )
    {
      htmlCode[ i ] = "&#" + i + ";" ;
    }
  }

  public static String encode( String string )
  {
    string = string.trim() ;
    int n = string.length() ;
    char character ;
    StringBuffer buffer = new StringBuffer() ;
    // loop over all the characters of the String.
    for( int i = 0 ; i < n ; i++ )
    {
      character = string.charAt( i ) ;
      // the Htmlcode of these characters are added to a StringBuffer one by one
      if( character < 256 )
      {
        buffer.append( htmlCode[ character ] ) ;
      }
      else
      {
        // Improvement posted by Joachim Eyrich
        buffer.append( "&#" ).append( ( int )character ).append( ";" ) ;
      }
    }
    return buffer.toString().trim() ;
  }
}
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11900145
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900190
not all the times,

but some times it is giving a problem
0
 
LVL 30

Assisted Solution

by:mayankeagle
mayankeagle earned 80 total points
ID: 11900200
>> for (int i = 0; i < special.length(); i++) {

You can also try to optimize that. Instead of finding out the String's length everytime you check that condition, do it only once.

int len = special.length () ;

for ( int i = 0 ; i < len ; i ++ )

Also - try using StringBuffers as suggested. BTW, what was the problem with URLEncoder?
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900213
main = main.replaceAll("\\\\", "_xf8fe_");

consider this

actual the return should be _xf8fe_ in my case, but it is returning %5c which is not right in this case
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11900223
> actual the return should be _xf8fe_ in my case, but it is returning %5c which is not right in this case

I don't understand...  Oh, and sorry, my code is wrong...I didn't read the question right :-(
0
 
LVL 30

Assisted Solution

by:mayankeagle
mayankeagle earned 80 total points
ID: 11900225
Which version are you working with?
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900238
0
 
LVL 30

Assisted Solution

by:mayankeagle
mayankeagle earned 80 total points
ID: 11900245
>> main = main.replaceAll("\\\\", "_xf8fe_");
>> //main=java.net.URLDecoder.decode(main);

>> actual the return should be _xf8fe_ in my case, but it is returning %5c which is not right in this case

You mean that the URLEncoder is returning %5c, though it should be returning _xf8fe_ there?
0
 
LVL 30

Expert Comment

by:mayankeagle
ID: 11900259
>> You mean that the URLEncoder

I meant URLDecoder.
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900265
Yes,

I try to explain my scenario

We are working with the exchange server related project

When we send a message to destination user, Exchange Server maintains the message with the name of Subject

for example if i give Subject as Test\ Hello

It stores the message in Test_xF8FE_%20Hello.EML file

So now encoding and decoding using URLEncoder/URLDecoder is giving problems in such cases

0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900716
I need method some thing like this which i am not getting using URLEncoder and URLDecoder

www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21044166.html
www.experts-exchange.com/Programming/ Programming_Languages/C_Sharp/Q_21044071.html

But with efficient proccess
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900734
Just found the similar link http://cvs.gnome.org/viewcvs/evolution-exchange/lib/e2k-uri.c?rev=1.2

All are doing more or less similar to me

I know the way but wanted to have best way

Hashtable is OK, I was thinkinging in the same way, but only with replace method
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900765
Instead of using replaceAll, I think I have to use StringBuffer for this.

Let me check the speed wth the modified code

0
 
LVL 30

Expert Comment

by:mayankeagle
ID: 11900981
The replace () method of StringBuffer takes 2 ints (start-index, end-index) as parameter, so I don't know if it'll be more efficient or not (because you need to make another call to indexOf () to get the start-index). Still, worth a try.
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11900996
Sridhar,

Here is the Idea I am approaching now. Let me know if it contains any peformance problems

thanks
sudhakar

package prithvi.util;
import java.util.*;

class  Encoder
{
      private static final HashMap encodes=new HashMap();
      static
      {

            encodes.put(new Character((char)0)  ,   "%0");
            encodes.put(new Character((char)1)  ,   "%1");
            encodes.put(new Character((char)2)  ,   "%2");
                //and so on

            /*for(int i=0;i<=255;i++)
            {
                  //encodes.put();
                  System.out.println("encodes.put(new Character((char)"+i+")  ,   " +"\"%"+Integer.toHexString(i)+"\");");

            }*/
      }
      static final String getEncodeValue(char c)
      {
            return (String)encodes.get(new Character(c));
      }

      public static String getEncodeValue(String str)
      {
            StringBuffer sb=new StringBuffer();
            for(int i=0;i<str.length();i++)
            {
                  char c=str.charAt(i);
                  if((c>='0'  && c<='9') || (c>='A' && c<='Z') ||(c>='a' && c<='z'))
                  {
                        sb.append(c);
                  }
                  else
                  {
                        sb.append(getEncodeValue(c));
                  }
            }
            return sb.toString();
      }

      public static void main(String s[])
      {
            System.out.println(getEncodeValue(s[0]));
      }


}

0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 30

Expert Comment

by:mayankeagle
ID: 11901040
Ah, that approach looks better. I was under the impression that you wanna change the calls to replaceAll () with calls to the StringBuffer's replace ().

>> for(int i=0;i<str.length();i++)

I still see the str.length () ; there, though you would be better off by storing it in a variable rather than calling the length () method so many times.

int len = str.length () ;

for ( int i = 0 ; i < len ; i ++ )
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11901093
ok,

I will take care of that
0
 
LVL 21

Assisted Solution

by:MogalManic
MogalManic earned 20 total points
ID: 11901176
Try this function (assuming main and special are the same string):
  private String replaceSpecial(String special)
  {
    StringBuffer newString=new StringBuffer(special);
    final String invalidChars=":?*/\"<>\\|&";
    for(int cIdx=0;cIdx<invalidChars.length();cIdx++) {
      int cPos;
      String eachCh=String.valueOf(invalidChars.charAt(cIdx));
      while((cPos=newString.indexOf(eachCh))>0) {
         char ch=newString.charAt(cPos);
         String hexCh=Integer.toHexString(ch);
         newString.replace(cPos, cPos+1, "%"+hexCh);
       }
    }
            
    return newString.toString();
}
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11901185
Sridhar,

Here is another question for you. Ofcourse for all of us :-)

http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_21108036.html
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11901202
Please say how and when URLEncoder.encode is not working for you
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11901204
MogalManic,

thanks for your reply. Actually we can do that using URLEncoder.encode itself  

But here is the scenario for some situations


When we send a message to destination user, Exchange Server maintains the message with the name of Subject

for example if i give Subject as Test\ Hello

It stores the message in Test_xF8FE_%20Hello.EML file and this is just an example with \, like that i need to replace maximum chars which comes under such special cases such as _xF8FF_ , _xF8EA_ and so on

So now encoding and decoding using URLEncoder/URLDecoder is giving problems in such cases
0
 
LVL 21

Expert Comment

by:MogalManic
ID: 11901249
Just write a simple function that replaces the UTF characters with whitespace before calling URLEncoder/Decoder
String FixUnicode(String str)
{
   StringBuffer s=new StringBuffer(str);
   for(int i=0;i<s.length();i++) {
     if (s.charAt(i)>128)
       s.replaceChars(i, i+1, " ");
   }
   return s.toString();
}
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11901435
http://192.12.0.38/exchange/Administrator/Sent%20Items/Test_xF8FE_%20Subject.EML

If i decode, So what should be result for this according to your method

Thanks
Sudhakar
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11901461
>>for example if i give Subject as Test\ Hello ...

That's fairly typical M$ non-standards-based stuff. You should determine by experiment the full range of possibilities. Only then will you be able to cope with them.

0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11902237
>>That's fairly typical M$ non-standards-based stuff. You should determine by experiment the full range of possibilities. Only  then will you be able to cope with them.

That is the reason I am writing my own method :-)
0
 
LVL 13

Expert Comment

by:Webstorm
ID: 11905633
Hi sudhakar_koundinya,

URLEncoder and URLDecoder should work. But theses 2 classes don't encode/decode UTF-8 encoded URL.

To optimize the code, you should avoid the new operator, and no HashMap is needed. You can also compile it with the following arguments:
  javac -O -g:none ...


package prithvi.util;
import java.util.*;

class  Encoder
{
     public static String getEncodeValue(String str)
     {
          StringBuffer sb=new StringBuffer(str.length());
          for(int i=0;i<str.length();i++)
          {
               char c=str.charAt(i);
               if((c>='0'  && c<='9') || (c>='A' && c<='Z') ||(c>='a' && c<='z'))
                    sb.append(c);
               else
               {
                    sb.append('%');
                    sb.append(Integer.toHexString(c));
               }
          }
          return sb.toString();
     }

     public static void main(String s[])
     {
          System.out.println(getEncodeValue(s[0]));
     }


}

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11905781
Webstorm - how does the functionality of that differ from that of URLEncoder, apart from omitting certain characters that don't need encoding?
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11905784
>>UTF-8 encoded URL.

If this is not, what other  supported character encoding i suould use. If that works for me. That will reduce much code for me

thanks
sudhakar
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11905837
>>That is the reason I am writing my own method :-)

I know ;-). Have you determined their encoding rules? If so - what did you find?
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11905854
>> But theses 2 classes don't encode/decode UTF-8 encoded URL.

JAVADoc says this

public static String encode(String s,
                            String enc)
                     throws UnsupportedEncodingException

    Translates a string into application/x-www-form-urlencoded format using a specific encoding scheme. This method uses the supplied encoding scheme to obtain the bytes for unsafe characters.

    Note: The World Wide Web Consortium Recommendation states that UTF-8 should be used. Not doing so may introduce incompatibilites.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11905921
>>Not doing so may introduce incompatibilites.

Indeed, which is why, presumably, they're doing things like:

>>Test_xF8FE_%20Subject.EML

Incidentally, the character with that code is called

'CJK COMPATIBILITY IDEOGRAPH-2F8FE'
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11905935
>>Have you determined their encoding rules? If so - what did you find?

As this project is related to Exchange Server

I generated the mails which takes the subject  string from 0-255 Ascii charachters.
And Identified the corresponding special characters. I know ths is just hit and trial method. If  you know correct encoding for such scenarios, plz let me know

thanks
sudhakar

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11906015
>>If  you know correct encoding for such scenarios, plz let me know

I don't i'm afraid. If you're very lucky, they may tell you somwhere. Failing that, i'd iterate every character from \u0000 to \uFFFF and find out
0
 
LVL 30

Expert Comment

by:mayankeagle
ID: 11910473
>> I generated the mails which takes the subject  string from 0-255 Ascii charachters.

You could also put those in a properties-file and load the properties at start-up.
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 11919674
I end up with using StringBuffer  and Hashmap usage


Thanks for ur inputs
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11920259
? Must say quite puzzled as to how and why points have been allocated here ...
0
 
LVL 30

Expert Comment

by:mayankeagle
ID: 11928304
Sudhakar,

I see three of my comments as assists, though only one of them seems to be helpful. Others were questions.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now