I make apps for other people


How to recover passwords from Oracle SQL Developer

Posted by Chris Jones
On January 6th, 2011 at 16:48

Permalink | Trackback | Links In |

Comments (1) |
Posted in General

import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;

 * Decrypt passwords stored in Oracle SQL Developer.
 * This is intended for password recovery.
 * Passwords are stored in ~/.sqldeveloper/system2.
public class Decrypt {
  public static byte[] decryptPassword(byte[] result) throws GeneralSecurityException {
    byte constant = result[0];
    if (constant != (byte)5) {
        throw new IllegalArgumentException();

    byte[] secretKey = new byte[8];
    System.arraycopy(result, 1, secretKey, 0, 8);

    byte[] encryptedPassword = new byte[result.length - 9];
    System.arraycopy(result, 9, encryptedPassword, 0, encryptedPassword.length);

    byte[] iv = new byte[8];
    for (int i = 0; i < iv.length; i++) {
        iv[i] = 0;

    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey, "DES"), new IvParameterSpec(iv));
    return cipher.doFinal(encryptedPassword);

  public static void main(String [] args) {
    if (args.length != 1) {
      System.err.println("Usage:  java Decrypt <password>");

    if (args[0].length() % 2 != 0) {
      System.err.println("Password must consist of hex pairs.  Length is odd (not even).");

    byte [] secret = new byte[args[0].length() / 2];
    for (int i = 0; i < args[0].length(); i += 2) {
      String pair = args[0].substring(i, i + 2);
      secret[i / 2] = (byte)(Integer.parseInt(pair,16));

    try {
      System.out.println(new String(decryptPassword(secret)));
    } catch (GeneralSecurityException e) {

Discovery in distributed networks

Posted by Chris Jones
On August 27th, 2010 at 06:56

Permalink | Trackback | Links In |

Comments Off on Discovery in distributed networks
Posted in General

Hierarchy – like DNS, a root authority (or several root authorities) provide structure. Multi-level caching reduces overall network congestion from name requests.

Anarchy – relying on broadcast and relay, nodes locally cache addresses and actively look up target nodes. Without aggressive caching (and large cache tables), anarchic networks break down under broadcast storms.

Cellular – aka “bang path” or peer-to-peer, a network node is aware of its immediate neighbors or connections but has to forward requests. This is an anarchic network and works well with limited nodes or limits on the depth of a broadcast, as could be seen in file sharing networks.

Self-organizing – a hybrid of cellular networks (awareness of neighbors) with a hierarchical network, certain nodes are elected to become caches for address resources (such as in NTLM). Taken a step further, these networks can actively rearrange relationships between peers to optimize hierarchies.

Most isolated place in Azeroth

Posted by Chris Jones
On August 14th, 2010 at 14:47

Permalink | Trackback | Links In |

Comments Off on Most isolated place in Azeroth
Posted in General

Shatterspear Vale

Shatterspear Vale

Four out of the box ideas for work

Posted by Chris Jones
On June 14th, 2010 at 11:48

Permalink | Trackback | Links In |

Comments Off on Four out of the box ideas for work
Posted in General

1. Use improv the illustrate process descriptions. You’ll be able to see and understand the process in a different way and can help identify errors and bottlenecks before going too deep into design.

2. Hire an artist to capture requirements and planning meetings. Artists interpret and capture meaning, unlike photographs.

3. Put a big HDTV in the team space for planning, tracking, and visualizing burndown, etc.

4. Extreme interviewing: bring in multiple candidates and make them work together. See if they have good kindergarten skills and if they will have the right team motivation and instincts to work with your current team.

The Halls of Reflection (Heroic) tax

Posted by Chris Jones
On December 27th, 2009 at 21:54

Permalink | Trackback | Links In |

Comments (1) |
Posted in General

After my, what, 30th wipe in Halls of Reflection Heroic, this time to a tank that wouldn’t pull waves back to the group but kept trying to fight on the altar, finally keeping Falric out of my healing range after I was feared in the opposite direction, I’m convinced Halls of Reflection is actually a gold tax on people using the random group tool.

I’ve run it successfully despite a lot of bad pugs but I much prefer doing it with a guild group. Becky saw how bad it was on normal mode today when she ran it with one of her Hunters. By comparison, Forge of Souls and Pit of Saron are cakewalks.

Maybe it’s because Halls of Reflection is a healing test, or maybe it’s because most pugs can’t seem to assist. When I ran it earlier today on Normal mode, I made sure everyone knew to assist off the main tank (a mediocre Death Knight, but it’s tough to be a good DK tank). At the least, a successful HoR group can pull 3k DPS per character, minus the healer and maybe the tank — any less and I’m out of mana or dead before I can keep the group’s health up. I feel like HoR was really built around the Holy Priest, even more so than the Tribunal encounter in Halls of Stone.

G13 WoW UI layout

Posted by Chris Jones
On December 25th, 2009 at 22:42

Permalink | Trackback | Links In |

Comments Off on G13 WoW UI layout
Posted in General

Here’s my updated UI for World of Warcraft.

Buttons are laid out to match the Logitech G13 — the exact choice for each button is still being tweaked, but it’s pretty close to done. Main chat and Grid are next to each other to watch player health, discussion, and DBM warnings in the chat log.

Tanking is done using the same UI with different buttons (replacing the set by virtue of the extra bar groups with multiple talent specs).


Notes on Spring development

Posted by Chris Jones
On August 15th, 2009 at 21:28

Permalink | Trackback | Links In |

Comments (3) |
Posted in General

3.0.0.M3 library problems
I haven’t tried 3.0.0.M4 with my new development environment yet, but I had missing class and Antlr problems with 3.0.0.M3. I ended up using 3.0.0.CI-319 at the time to get a working Spring framework.

Creating a logging bean
Create an annotation package with a Log interface:

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
* Injects a logger of an appropriate type into beans.
public @interface Log {

Create a logger injector:

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;
* Auto injects the commons Log implementation into the bean when a field is annotated
* with Logger.
public class LoggerInjector implements BeanPostProcessor {
  private static Map>String , Logger< loggers = new HashMap>String , Logger<();
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        // make the field accessible if defined private
        if (field.getAnnotation(Log.class) != null) {
          String cls = bean.getClass().getName();
          Logger logger = null;
          if (loggers.containsKey(cls)) {
            logger = loggers.get(cls);
          } else {
            logger = Logger.getLogger(cls);
            loggers.put(cls, logger);
          field.set(bean, logger);
    return bean;

Declare your logger bean in your application context:

<bean class="mypackage.annotation.LoggerInjector"/>

Attach the Logger to your class:

import org.apache.log4j.Logger;
import mypackage.annotation.Log;
// in your class fields
* Logger
private Logger logger;
// use it
logger.error("Invalid request type: " + requestType);

Interface-oriented design
Define your data objects and factories as interfaces (methods), then provide factory implementations to create or retrieve instances of your data objects:

<bean id="myDaoFactory" class="mypackage.factory.myDaoFactoryImpl"
  factory-method="getFactory" scope="singleton"/>

Use the Autowired annotation to automatically add beans to your consuming classes.

* Storage engine.
private Storage storage;

Non-SQL databases
Non-SQL databases should be handled through high level “use case” calls against a storage engine rather than direct puts and gets.


Posted by Chris Jones
On July 29th, 2009 at 18:39

Permalink | Trackback | Links In |

Comments (1) |
Posted in General

The Sound is evaporating away. I can barely see Kitsap, and the Olympics are lost in the haze.

I daresay, I may need to turn off my laptop. It’s running at about 110 F to the touch.

Seattle’s record 102 degrees is made that much worse by living in a house with air conditioning. “You won’t need it. It only gets hot a couple times a year, a week or two at the most, and it never goes above 90 and it’s never that humid.” Heh.

Tomorrow should be better.

Awww cute!

Posted by Chris Jones
On June 25th, 2009 at 13:05

Permalink | Trackback | Links In |

Comments Off on Awww cute!
Posted in General

Becky got a baby raptor companion pet last night on the WoW 3.2 PTR. She said it was her fifth run through the instance, which means it’s about a 1 in 100 drop rate, similar to the Sprite Darter in Feralas.

Munchkin in the morning

Posted by Chris Jones
On June 25th, 2009 at 07:59

Permalink | Trackback | Links In |

Comments Off on Munchkin in the morning
Posted in General

My wife wanted to know if it was worth going Engineering on a Troll hunter and lose the +1% crit bonus to bows to use crafted shot instead.

Think about crit this way:
– For the sake of argument, you hit the mobs for 150 with a shot with
vendor ammo. You fire a shot every 2.7 seconds, and your hit is 2.2%,
meaning your miss rate is 3.7%, giving an effective hit of 144.45. Your
ideal DPS is 55.56, but with your miss, you’re really down to 53.5 DPS.
– 1% crit means one out of 100 shots will crit for up to double damage.
For the purpose of this discussion, we’ll assume it always does double
– In case A, we’ll say you have +3% crit for this discussion, or 8% crit
actual, which means your damage effective over 300 shots is (144.45 * 300
shots + 150 * 24 crits) or 43335 + 3600 = 46,935 damage, or effective
57.94 DPS
– In case B, we’ll say you have +2% crit, or 7% crit actual, which means
your damage effective over 300 shots is (21 crits) 43335 + 3150 = 46,485
damage or effective 57.39 DPS.

So, as was said on Wowwiki:
What’s better, +to hit or +crit?

In principle they are equal. Which is better depends on circumstances. An
increase in hit rate will usually yield a constant level of damage,
whereas a high crit chance gives a spiky, more random damage distribution
over time.

(With the additional caveat that crits are sometimes dropped because the
attack table is full against a mob, and crits are rolled separately.)

You can see when comparing 57.94 DPS versus 57.39 DPS that they’re almost
equal, and that the difference of .5 DPS from using crafted shot negates
the penalty for not using bows.

Totally worth being 30 minutes later for the bus…