I need:
// SOURCE
class A {
public B B;
public C C;
}
class B { public int X; }
class C { public int Y; }
// DESTINATION
class D {
public int X;
public int Y;
}
// I want to configure following operation
// without mapping each (X and Y) fields explicitly.
D.X = A.B.X;
D.Y = A.C.Y;
// here is the essence of what I am trying to accomplish.
Mapper.CreateMap<B, D>();
Mapper.CreateMap<C, D>();
var map = Mapper.CreateMap<A, D>();
map.ForMember(dst => dst, opt => opt.MapFrom(src => src.B));
map.ForMember(dst => dst, opt => opt.MapFrom(src => src.C));
Any suggestions?
Note: I am aware that if I change D.X to D.BX and D.Y to D.CY it will work. I want to accomplish this without prefixing D's properties. I also can accomplish this by using "Fill" version of the Map.
// I want to configure following operation
// without mapping each (X and Y) fields explicitly.
D.X = A.B.X;
D.Y = A.B.Y;
According to your class, B does not have a Y. B has an X. Did you mean D.Y = A.C.Y? If so:
Mapper.CreateMap<A, D>()
.ForMember(d => d.X, o => o.MapFrom(s => s.B.X))
.ForMember(d => d.Y, o => o.MapFrom(s => s.C.Y))
;
Related
I want to create a programming language that has multiple functions and a single main function. For the interpreter of the language I am using a hash map, but I do not know how to store intermediate values in the hash map. An example of a valid program includes:
DEF MAIN { ADDITION(4) } ;
DEF ADDITION x { x+3 } ;
This is what I have so far:
HashMap<String, Function> Program() : {
HashMap<String, Function> symbolTable = new HashTable<>();
}
{
(FunctionDefinition(symbolTable))*
<EOF>
{return symbolTable;}
}
void FunctionDefinition(SymbolTable table)
{
Function f;
String name;
}
{
<DEF> <SPACE>
(
(name = <MAIN>)
| (name = <FUNC> (<SPACE> <PARAM> ))
<SPACE>
f = FunctionBody()
";"
{
if (table.hashKey(name)) { System.out.println("do something");}
else { table.add(name, f); }
})
}
void FunctionBody() : {}
{
<LEFT> <SPACE>
Expression()
<SPACE> <RIGHT>
}
void Expression() : {}
{
AdditiveExpression()
}
void AdditiveExpression() : {
}
{
MultiplicativeExpression() (<PLUS> MultiplicativeExpression()
{
try {
int a = s.pop();
int b = s.pop();
stack.push(a+b);
}
catch (ClassCastException ex) {
System.out.println("Only numbers can be used for arithmetic operations.");
throw new ParseException();
}
})*
}
void MultiplicativeExpression() : {
}
{
UnaryExpression() (<MUL> UnaryExpression()
{
try {
int a = s.pop();
int b = s.pop();
stack.push(a*b);
}
catch (ClassCastException ex) {
System.out.println("Only numbers can be used for arithmetic operations");
throw new ParseException();
}
})*
}
void UnaryExpression() : {
Token x;
}
{
(x = <NUMBER> | x = <PARAM>)
{s.push(x.image);}
}
Any help will be greatly appreciated.
As #Theodore has said, you can't execute the program while you're parsing it. I thought I'd add my two cents here.
The result of the parsing could be the table of functions though, and you would have a main method that would do something like this:
Parser parser = new Parser(System.in, "UTF-8");
Map<String, Function> table = parser.program();
Function main = table.get("MAIN");
if (main == null) {
System.out.println("Function MAIN doesn't exist");
} else {
int r = main.invoke(table);
System.out.println("Result: " + r);
}
I see a few weird things in your code:
Instead of using a token <SPACE> between each token, you'd be better off using the SKIP instruction:
SKIP : { " " | "\r" | "\n" | "\t" }
You're using three different tokens for the same thing: <MAIN>, <FUNC>, <PARAM>. They're all names, and you could define a token <NAME> as follows:
TOKEN: {
< NAME: <LETTER>(<LETTER>|<DIGIT>)* >
| < #LETTER: ["a"-"z", "A"-"Z", "_"] >
| < #DIGIT: ["0"-"9"] >
}
The rule for a function definition would then become:
<DEF> <NAME> ( <NAME> )* functionBody() ";"
note that a function can have zero or more parameters; function MAIN would have zero.
In your example, function MAIN contains a forward reference to the function ADDITION, meaning that while parsing the body of function MAIN you will find a call to a function ADDITION that is not yet in the symbol table. The ability to use forward reference is a nice feature for a programming language, but it complicates the implementation slightly.
If you're doing an interpreter, you have basically two options to deal with forward references: 1) do a second pass after the parsing to "fix" the forward references, 2) do the name resolution during run time. The second option is simpler but slower.
Note that the parameters of a function are always defined before they are used. They are only accessible within the body of a function. You can build a table for the parameter while parsing the head of the definition, and then pass that table to the method that parses the body of the function.
Example:
void functionDefinition(Map<String, Function> table): {
Expression body;
Function f;
String name;
String param;
int paramCount = 0;
Map<String,Parameter> params = new HashMap<String,Parameter>();
}
{
<DEF> name=<NAME>.image (
param=<NAME>.image {params.put(param, new Parameter(paramCount++));}
)*
body=functionBody(params)
{ f = new Function(paramCount, body); }
";"
{
if (table.containsKey(name)) {
System.out.println("Function " + name + "already exists");
} else {
table.put(name, f);
}
}
}
To evaluate the expression in a function body, you can use the interpreter pattern, where the elements of an expression are all an implementation of an Expression interface:
public interface Expression {
public int evaluate(Map<String,Function> table, int... parms);
}
Here parms are the actual parameters passed to the function being executed.
The following files are the sources of a very simple, functioning implementation of a very simple language based on your question. It can execute your example:
DEF MAIN { ADDITION(4) } ;
DEF ADDITION x { x+3 } ;
and it can also execute something like this:
DEF MAIN { ADDITION3(4) } ;
DEF ADDITION3 x { ADDITION(x,3) } ;
DEF ADDITION x y { x+y } ;
I hope it will help.
JavaCC file, parser.jj:
options {
STATIC = false;
IGNORE_CASE = false;
}
PARSER_BEGIN(Parser)
package org.tastefuljava.minilang;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
public class Parser {
public static void main(String[] args) {
try {
Parser parser = new Parser(System.in, "UTF-8");
Map<String, Function> table = parser.program();
int r = Expression.call("MAIN").evaluate(table);
System.out.println("Result: " + r);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
PARSER_END(Parser)
SKIP : { " " | "\r" | "\n" | "\t" }
TOKEN: {
< DEF: "DEF" >
| < NAME: <LETTER>(<LETTER>|<DIGIT>)* >
| < #LETTER: ["a"-"z", "A"-"Z", "_"] >
| < #DIGIT: ["0"-"9"] >
| < PLUS: "+" >
| < MUL: "*" >
| < LEFT: "{" >
| < RIGHT: "}" >
| < NUMBER: (<DIGIT>)+ >
}
Map<String, Function> program(): {
Map<String, Function> symbolTable = new HashMap<>();
}
{
(functionDefinition(symbolTable))*
{return symbolTable;}
}
void functionDefinition(Map<String, Function> table): {
Expression body;
Function f;
String name;
String param;
int paramCount = 0;
Map<String,Parameter> params = new HashMap<String,Parameter>();
}
{
<DEF> name=<NAME>.image (
param=<NAME>.image {params.put(param, new Parameter(paramCount++));}
)*
body=functionBody(params)
{ f = new Function(paramCount, body); }
";"
{
if (table.containsKey(name)) {
System.out.println("Function " + name + "already exists");
} else {
table.put(name, f);
}
}
}
Expression functionBody(Map<String,Parameter> params): {
Expression e;
}
{
<LEFT>
e=expression(params)
<RIGHT>
{
return e;
}
}
Expression expression(Map<String,Parameter> params): {
Expression e;
}
{
e=additiveExpression(params)
{
return e;
}
}
Expression additiveExpression(Map<String,Parameter> params): {
Expression e, f;
}
{
e=multiplicativeExpression(params)
(<PLUS> f=multiplicativeExpression(params) {
e = Expression.add(e,f);
})*
{
return e;
}
}
Expression multiplicativeExpression(Map<String,Parameter> params): {
Expression e, f;
}
{
e=unaryExpression(params) (<MUL> f=unaryExpression(params) {
e = Expression.mul(e,f);
})*
{
return e;
}
}
Expression unaryExpression(Map<String,Parameter> params): {
Expression e;
String s;
int n;
Expression[] parms;
}
{
(
n=number() {
e = Expression.number(n);
}
| s=<NAME>.image ( parms=parameterList(params) {
e = Expression.call(s, parms);
} | {
Parameter p = params.get(s);
if (p != null) {
e = Expression.param(p.index);
} else {
// no parameter found: assume it's a parameterless function
e = Expression.call(s);
}
})
)
{
return e;
}
}
int number(): {
String s;
}
{
s=<NUMBER>.image
{
return Integer.parseInt(s);
}
}
Expression[] parameterList(Map<String,Parameter> params): {
List<Expression> parms = new ArrayList<Expression>();
Expression p;
}
{
"("
(
p=expression(params) { parms.add(p); }
( "," p=expression(params){ parms.add(p); } )*
)?
")"
{
return parms.toArray(new Expression[parms.size()]);
}
}
Function class, Function.java:
package org.tastefuljava.minilang;
public class Function {
public final int paramCount;
public final Expression body;
public Function(int paramCount, Expression body) {
this.paramCount = paramCount;
this.body = body;
}
}
Parameter class, Parameter.java:
package org.tastefuljava.minilang;
public class Parameter {
public final int index;
public Parameter(int index) {
this.index = index;
}
}
Expression interface, Expression.java:
package org.tastefuljava.minilang;
import java.util.Map;
public interface Expression {
public int evaluate(Map<String,Function> table, int... parms);
public static Expression number(int x) {
return (table, parms) -> x;
}
public static Expression add(Expression a, Expression b) {
return (table, parms) ->
a.evaluate(table, parms) + b.evaluate(table, parms);
}
public static Expression mul(Expression a, Expression b) {
return (table, parms) ->
a.evaluate(table, parms) * b.evaluate(table, parms);
}
public static Expression call(String name, Expression... parms) {
return (table, oldParms) -> {
Function f = table.get(name);
if (f == null) {
System.out.println("Unknown function " + name);
return 0;
} else if (f.paramCount != parms.length) {
System.out.println("Wrong number of parameters for function "
+ name + ": expected " + f.paramCount
+ ", actual " + parms.length);
return 0;
}
int[] newParms = new int[parms.length];
for (int i = 0; i < parms.length; ++i) {
newParms[i] = parms[i].evaluate(table, oldParms);
}
return f.body.evaluate(table, newParms);
};
}
public static Expression param(int index) {
return (table, parms) -> parms[index];
}
}
You need your FunctionBody nonterminal to return the intermediate representation for the function.
The problem is that you don't have an intermediate representation. You are trying to do direct interpretation, i.e. you are executing the program at the same time that it is parsed. That's fine for simple interactive calculators like the one in this ancient tutorial. However, once you start dealing with loops and functions you really need to generate (and later execute) intermediate code. See this FAQ for why.
If you are are taking a course, ask your instructor what he or she or they would recommend for intermediate code.
If you don't have an instructor, my advice is to generate machine code for a stack machine, since you are already using a stack for execution. See, for example, my notes on generating machine code for a stack machine in a recursive descent parser, especially pages 14 to 20; I didn't use a parser generator for this, but that shouldn't matter. (I use ^ for sequence concatenation, so, for example, m := m^div just means add a div instruction to the end of the intermediate representation.)
Any book on compilers will also cover this sort of stuff.
Tom Copeland's book probably has lots more information and is JavaCC specific.
I have a svg element, let's say a group, that has applied matrix rotation to it. I want to use svgmatrix api to flip it regarding root / screen axis.
Solution found as #enxaneta suggested, is to wrap element in a pristine group and apply the flipping to it, offloading the work math to the engine / browser. This way any transformations will be preserved
export const mirror = ($el, k) => {
if (!$el) return
// flip horizontall or vertical
if (k !== 1 && k !== -1) return false
// create a group from element
const $g = newtag('g')
const $father = $el.parentElement || $el.ownerSVGElement
const $next = $el?.nextElementSibling
$next
? $father.insertBefore($g, $next)
: $father.appendChild($g)
$g.appendChild($el)
// get matrix of group
let xg = m($g)
let bb = $g.getBBox()
let x = bb.x+bb.width/2
let y = bb.y+bb.height/2
if (k === -1) {
xg = xg.flipY().translate(0, -2*y)
} else if (k === 1) {
xg = xg.flipX().translate(-2*x, 0)
}
// apply transformations to the group
setm($g, xg)
// preserve transformations applied to group wrapped element
// so when will be extracted from group it will have them
const xel = m2e($el, $father)
$father.insertBefore($el, $g)
setm($el, xel)
$g.remove()
}
const m = e => e.transform.baseVal.consolidate()?.matrix || e.ownerSVGElement?.createSVGMatrix() || e.createSVGMatrix()
const setm = (e, m) =>e.transform.baseVal.initialize(e.ownerSVGElement?.createSVGTransformFromMatrix(m))
const newtag = (n, v=null) => {
n = document.createElementNS(xmlns, n);
n.setAttributeNS(null, 'id', '_'+rnd())
if (!v) return n
attr(n, v)
return n
}
const attr = (n, v=null) => {
for (let p in v){
n.setAttributeNS(null, p.replace(/[A-Z]/g, (m, p, o, s) => "-" + m.toLowerCase()), v[p])
}
}
const m2e = (a,e) => {
if (!e) e = a.ownerSVGElement
return e.getScreenCTM().inverse().multiply(a.getScreenCTM())
}
Assuming I have the following classes in Haxe:
class Pair<U, V> {
public var first:U = null;
public var second:V = null;
public function new(u:U, v:V) {
this.first = u;
this.second = v;
}
}
class HashablePair<U:{ function hashCode():Int; }, V:{ function hashCode():Int; }> {
public var first:U = null;
public var second:V = null;
public function new(u:U, v:V) {
this.first = u;
this.second = v;
}
public function hashCode():Int { // just a sample way ...
var h1:Int = (first == null) ? 0 : first.hashCode();
var h2:Int = (second == null) ? 0 : second.hashCode();
return 3 * h1 + 5 * h2;
}
}
I wondered if it is possible to write a macro that adds the hashCode function to the pair class, if and only if both generics U and V implement the hashCode-function ... and thus make it possible to combine the two classes into a single one via meta-programming.
You can achieve the desired behavior by simply switching to an abstract:
typedef Hashable = { function hashCode():Int; };
abstract HashablePair<U:Hashable,V:Hashable>(Pair<U,V>)from Pair<U,V> {
public function new(u:U, v:V)
this = new Pair(u, v);
public function hashCode():Int { // just a sample way ...
var h1:Int = (this.first == null) ? 0 : this.first.hashCode();
var h2:Int = (this.second == null) ? 0 : this.second.hashCode();
return 3 * h1 + 5 * h2;
}
}
The from Pair<U,V> makes Pair<U,V> casts to HashablePair<U,V> allowed, as long as the necessary constrains on U and V are respected.
For a complete exemple, check out Try Haxe #d76E1.
I want to get the string representation of a lambda Func<> Expression to get the Property Path. I have this example
Expression<Func<Employee, object>> _xxx = e => e.EmployeeInfo.Addresses["Address"];
and i am expecting a string
"EmployeeInfo.Addresses["Address"]"
when i do _xxx.ToString(); i'll just do some string parsing and i can get the result above.
My problem is when i do
var _addrName = "Address";
Expression<Func<Employee, object>> _xxx = e => e.EmployeeInfo.Addresses[_addrName];
i got a very long string
"EmployeeInfo.Addresses.get_Item(value(UnitTestProj.UnitTest.AnyTest+<>c__DisplayClass0)._addr)"
which is very hard to manipulate to come up with
"EmployeeInfo.Addresses["Address"]"
Is there any way to achieve my purpose?
TIA
This should get you pretty far - it's very hacky but I don't think there's a way around it:
Expression<Func<Employee, object>> _xxx = e => e.EmployeeInfo.Addresses[address];
WriteLine(ExprToString(_xxx)); //e.EmployeeInfo.Addresses[address]
_xxx = x => x.EmployeeInfo.Addresses["XYZ"];
WriteLine(ExprToString(_xxx)); //x.EmployeeInfo.Addresses["XYZ"]
_xxx = y => y.EmployeeInfo.Addresses[null];
WriteLine(ExprToString(_xxx)); //y.EmployeeInfo.Addresses[null]
_xxx = z => z.EmployeeInfo.Name;
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.Name
_xxx = z => z.EmployeeInfo.GetSalary();
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.GetSalary()
_xxx = z => z.EmployeeInfo.Addresses.Select(a => a.Street);
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.Addresses.Select(a.Street)
_xxx = z => z.EmployeeInfo.Array[3];
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.Array[3]
The implementation:
static string ExprToString(Expression expr)
{
switch (expr.NodeType)
{
case ExpressionType.Lambda:
//x => (Something), return only (Something), the Body
return ExprToString(((LambdaExpression) expr).Body);
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
//type casts are not important
return ExprToString(((UnaryExpression) expr).Operand);
case ExpressionType.Call:
//method call can be an Indexer (get_Item),
var callExpr = (MethodCallExpression) expr;
if (callExpr.Method.Name == "get_Item")
{
//indexer call
return ExprToString(callExpr.Object) + "[" + string.Join(",", callExpr.Arguments.Select(ExprToString)) + "]";
}
else
{
//method call
var arguments = callExpr.Arguments.Select(ExprToString).ToArray();
string target;
if (callExpr.Method.IsDefined(typeof (ExtensionAttribute), false))
{
//extension method
target = string.Join(".", arguments[0], callExpr.Method.Name);
arguments = arguments.Skip(1).ToArray();
}
else if (callExpr.Object == null)
{
//static method
target = callExpr.Method.Name;
}
else
{
//instance method
target = string.Join(".", ExprToString(callExpr.Object), callExpr.Method.Name);
}
return target + "(" + string.Join(",", arguments) + ")";
}
case ExpressionType.MemberAccess:
//property or field access
var memberExpr = (MemberExpression) expr;
if (memberExpr.Expression.Type.Name.Contains("<>")) //closure type, don't show it.
{
return memberExpr.Member.Name;
}
else
{
return string.Join(".", ExprToString(memberExpr.Expression), memberExpr.Member.Name);
}
}
//by default, show the standard implementation
return expr.ToString();
}
I have a problem in which I have to SWAP or move characters and integers. Like I have any characters A . now I have some cases, like
NOTE:- Have to use characters A-Z and integers 0-9
A, now I want that when my program run I assign some integer value to this character, If I assign value 3 to this character then A will become D or it just move to 3 places.
Now if I have a character like Y and I add 4 then it will become C means after Z it will again start from character A.
Same condition I have to follow with Integer if i have 9 and we assign 3 to it then it will become 2 because loop start from 0 not from 1. Means we have to use only 0-9 integers.
I know that i am using wrong name to question but i have no idea that what lines i have to use for that kind of question.
Hope you understand my problem.
Thanks in advance.
Try the below extension method, which does the following:
It creates 2 dictionaries in order to speed up the key look up in the alphabet
Will parse the inputString variable, split it in substrings of the length of the moveString variable's length (or the remainder)
On every substring, it will evaluate each character in order to detect if it's a digit
If it's not a digit, it looks up for the value in the swappedAlphabet dictionary, by using the int key
If it's a digit, it applies a modulo operation on the sum of the digit and the corresponding moveint value
It finally aggregates all the characters in the final result string
Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
string
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string inputString = "ABC123D", moveString = "12";
var result = inputString.Swap(alphabet, moveString);
Console.WriteLine(result);
}
}
static class ExtensionMethods
{
public static Dictionary<TValue, TKey>
SwapKeysValues<TKey, TValue>(this Dictionary<TKey, TValue> input)
{
var result = new Dictionary<TValue, TKey>();
input.ToList().ForEach((keyValuePair) =>
{
result.Add(keyValuePair.Value, keyValuePair.Key);
});
return result;
}
public static string Swap(
this string input,
string alphabet,
string move)
{
Dictionary<char, int>
alphabetDictionary = new Dictionary<char, int>();
for (int i = 0; i < alphabet.Length; i++)
{
alphabetDictionary.Add(alphabet[i], i);
}
var swapedAlphabet = alphabetDictionary.SwapKeysValues();
return Enumerable
.Range(0, (int)Math.Ceiling(input.Length / (move.Length * 1M)))
.ToList()
.Aggregate<int, string>("", (s, i) =>
{
var l = i * move.Length + move.Length;
var cInput = input.Substring(i * move.Length,
(l > input.Length)
? input.Length - i * move.Length : move.Length);
return s + cInput
.Select((c, index) =>
{
int intCandidate;
if (!Int32.TryParse(c.ToString(), out intCandidate))
{
var length = (alphabetDictionary[c] +
Int32.Parse(move[index].ToString()));
return
swapedAlphabet[(alphabet.Length > length)
? length : length % alphabet.Length];
}
else
{
var moveInt = Int32.Parse(move[index].ToString());
return Char.Parse(((intCandidate + moveInt) % 10)
.ToString());
}
})
.Aggregate<char, string>("", (a, b) => a + b);
});
}
}
Another alternative you have is relying on the in-built character/integer types which follow the order you want; with an additional consideration: if you account for caps, it would deliver caps ("B" after "A" and "b" after "a"). The only thing you need to worry about is making sure that the iterations will be limited to the A-Z/0-9 boundaries. Sample code:
public string moveChar(string inputChar, int noPos)
{
string outChar = checkBoundaries(inputChar, noPos);
if (outChar == "")
{
outChar = basicConversion(inputChar, noPos);
}
return outChar;
}
public string basicConversion(string inputChar, int noPos)
{
return Convert.ToString(Convert.ToChar(Convert.ToInt32(Convert.ToChar(inputChar)) + noPos));
}
public string checkBoundaries(string inputChar, int noPos)
{
string outString = "";
int count1 = 0;
do
{
count1 = count1 + 1;
string curTemp = basicConversion(inputChar, 1);
if (inputChar.ToLower() == "z" || curTemp.ToLower() == "z")
{
if (inputChar.ToLower() != "z")
{
noPos = noPos - count1;
}
inputChar = "a";
outString = "a";
if (inputChar == "Z" || curTemp == "Z")
{
inputChar = "A";
outString = "A";
}
count1 = 1;
}
else if (inputChar == "9" || curTemp == "9")
{
if (inputChar != "9")
{
noPos = noPos - count1;
}
inputChar = "0";
outString = "0";
count1 = 1;
}
else
{
inputChar = curTemp;
outString = inputChar;
}
} while (count1 < noPos);
return outString;
}
It expects strings (just one character (letter or number) per call) and you can call it simply by using: moveChar("current letter or number", no_of_pos_to_move). This version accounts just for "positive"/"forwards" movements but it might easily be edited to account for the inverse situation.
Here's a very simple way to implement a Caesar Cipher with the restrictions you defined.
var shift = 3;
var input = "HELLO WORLD 678";
var classAlphabets = new Dictionary<UnicodeCategory, string>
{
{ UnicodeCategory.SpaceSeparator, " " },
{ UnicodeCategory.UppercaseLetter, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
{ UnicodeCategory.DecimalDigitNumber, "0123456789" }
};
var encoded = input.ToUpperInvariant()
.Select(c => new { Alphabet = classAlphabets[Char.GetUnicodeCategory(c)], Character = c })
.Select(x => new { x.Alphabet, Index = x.Alphabet.IndexOf(x.Character) })
.Select(x => new { x.Alphabet, Index = x.Index + shift })
.Select(x => new { x.Alphabet, Index = x.Index % x.Alphabet.Length })
.Select(x => x.Alphabet.ElementAt(x.Index))
.Aggregate(new StringBuilder(), (builder, character) => builder.Append(character))
.ToString();
Console.Write(encoded);
// encoded = "KHOOR ZRUOG 901"
Decoding is simply a case of inverting the shift.
Caesar cipher can be easier like this:
static char Encrypt(char ch, int code)
{
if (!char.IsLetter(ch))
{
return ch;
}
char offset = char.IsUpper(ch) ? 'A' : 'a';
return (char)(((ch + code - offset) % 26) + offset);
}
static string Encrypt(string input, int code)
{
return new string(input.ToCharArray().Select(ch => Encrypt(ch, code)).ToArray());
}
static string Decrypt(string input, int code)
{
return Encrypt(input, 26 - code);
}
const string TestCase = "Pack my box with five dozen liquor jugs.";
static void Main()
{
string str = TestCase;
Console.WriteLine(str);
str = Encrypt(str, 5);
Console.WriteLine("Encrypted: {0}", str);
str = Decrypt(str, 5);
Console.WriteLine("Decrypted: {0}", str);
Console.ReadKey();
}