#C#, 120 86 108 102102 92 bytes
x=I=>{var Z=I.Length;return Z%2<1?0>1:Z<2?1>0:I[0]==I[Z-1]&I[1]-0==I[0]+1?x(I.Substring(1,Z-2)):0>1;};
class a
{
static void Main()
{
Func<string, bool> x = null;
x = I=>
{
var Z=I.Length;
return Z%2<1? // Length mod 2?
0>1: // return false
Z==1? // else length == 1?
1>0: // return true (middle of #)
I[0]==I[Z-1]&I[1]-0==I[0]+1? // else start == end and the next number is 1 above the current?
x(I.Substring(1,Z-2)): // recursive call on middle
0>1; // else false
};
Console.WriteLine("1 -> " + (x("1") == true));
Console.WriteLine("9 -> " + (x("9") == true));
Console.WriteLine("121 -> " + (x("121") == true));
Console.WriteLine("12321 -> " + (x("12321") == true));
Console.WriteLine("4567654 -> " + (x("4567654") == true));
Console.WriteLine("12345678987654321 -> " + (x("12345678987654321") == true));
Console.WriteLine("12 -> " + (x("12") == false));
Console.WriteLine("1221 -> " + (x("1221") == false));
Console.WriteLine("16436346 -> " + (x("16436346") == false));
Console.WriteLine("123321 -> " + (x("123321") == false));
Console.WriteLine("3454321 -> " + (x("3454321") == false));
Console.WriteLine("13631 -> " + (x("13631") == false));
Console.WriteLine("191 -> " + (x("13631") == false));
Console.Read(); // For Visual Studio
}
}
Hooray for single line conditionals, now beating the Java answer :)! Also got to write my first explaining comments, though it's probably self explanatory. Thanks to @Dada for finding a problem with my algorithm (was true for numbers that were mirrored like 13631). Now sub 100 since apparently checking for length%2 is redundant.