Implementation of RC4 Encryption and URL encoding in objective c - ios

I've to implement the RC4 encryption algorithm in my application for URL encoding.The sample part is listed below for your reference.
Actual value Before Encryption : 10/28/2013
Expected value After Encryption : ˆ!˜·hÇÔÞò
After URL encoding it should be : %0C%88%21%98%B7h%C7%D4%DE%F2
KEY USED is:#"psw"
I've tried but value after encryption & URL encoding returns in this way:
After encryption : !·hÇÔÞò
After URL encoding : %0C%C2%88%21%C2%98%C2%B7h%C3%87%C3%94%C3%9E%C3%B2
I tried converting the java code into objective c code.The java code works fine ,were as the objective c is not working, which you can see in the above result.
Here is the Java code
import java.net.URLEncoder;
public class RC4 {
private char[] key;
private int[] sbox;
private static final int SBOX_LENGTH = 256;
private static final int KEY_MIN_LENGTH = 1;
public static void main(String[] args) {
try {
RC4 rc4 = new RC4("psw");
char[] result = rc4.encrypt("10/28/2013".toCharArray());
System.out.println("encrypted string:\n"
+ new String(toByteArray(result)));
System.out.println("decrypted string:\n"
+ new String(rc4.decrypt(result)));
System.out.println("decrypted string:\n"
+ URLEncoder.encode(new String(toByteArray(result))));
} catch (InvalidKeyException e) {
System.err.println(e.getMessage());
}
}
static byte[] toByteArray(char[] chars) {
byte[] bytes = new byte[chars.length];
for (int i = 0; i < chars.length; i++) {
// bytes[i*2] = (byte) (chars[i] >> 8);
bytes[i] = (byte) chars[i];
}
return bytes;
}
public RC4(String key) throws InvalidKeyException {
setKey(key);
}
public RC4() {
}
public char[] decrypt(final char[] msg) {
return encrypt(msg);
}
public char[] encrypt(final char[] msg) {
sbox = initSBox(key);
char[] code = new char[msg.length];
int i = 0;
int j = 0;
for (int n = 0; n < msg.length; n++) {
i = (i + 1) % SBOX_LENGTH;
j = (j + sbox[i]) % SBOX_LENGTH;
swap(i, j, sbox);
int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LENGTH];
code[n] = (char) (rand ^ (int) msg[n]);
}
return code;
}
private int[] initSBox(char[] key) {
int[] sbox = new int[SBOX_LENGTH];
int j = 0;
for (int i = 0; i < SBOX_LENGTH; i++) {
sbox[i] = i;
}
for (int i = 0; i < SBOX_LENGTH; i++) {
j = (j + sbox[i] + key[i % key.length]) % SBOX_LENGTH;
swap(i, j, sbox);
}
return sbox;
}
private void swap(int i, int j, int[] sbox) {
int temp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = temp;
}
public void setKey(String key) throws InvalidKeyException {
if (!(key.length() >= KEY_MIN_LENGTH && key.length() < SBOX_LENGTH)) {
throw new InvalidKeyException("Key length has to be between "
+ KEY_MIN_LENGTH + " and " + (SBOX_LENGTH - 1));
}
this.key = key.toCharArray();
}
public class InvalidKeyException extends Exception {
private static final long serialVersionUID = 1L;
public InvalidKeyException(String message) {
super(message);
}
}
}
Its corresponding Objective c Code
-(NSString *)encrypt:(NSString *)string{
[self frameSBox:#"psw"];
unichar code[string.length];
const unichar* buffer = code;
int i = 0;
int j = 0;
for (int n = 0; n < string.length; n++) {
i = (i + 1) % self.SBOX_LENGTH;
j = (j + [[self.sBox objectAtIndex:i]integerValue]) % self.SBOX_LENGTH;
[self swap:i with:j];
int index=([[self.sBox objectAtIndex:i] integerValue]+[[self.sBox objectAtIndex:j] integerValue]);
int rand=([[self.sBox objectAtIndex:(index%self.SBOX_LENGTH)] integerValue]);
code[n]=(rand ^ (int)[string characterAtIndex:n]);
}
buffer = code;
return [NSString stringWithCharacters:buffer length:string.length];
}
-(NSArray *)frameSBox:(NSString *)keyValue{
if (self.sBox == nil) {
self.sBox=[[NSMutableArray alloc]init];
}
self.SBOX_LENGTH=256;
int j = 0;
for (int i = 0; i < self.SBOX_LENGTH; i++) {
[self.sBox addObject:[NSNumber numberWithInteger:i]];
}
for (int i = 0; i < self.SBOX_LENGTH; i++) {
j = (j + [[self.sBox objectAtIndex:i] integerValue] + [keyValue characterAtIndex:(i % keyValue.length)]) % self.SBOX_LENGTH;
[self swap:i with:j];
}
return self.sBox;
}
-(void)swap:(int)i with:(int)j{
id tempObj = [self.sBox objectAtIndex:i];
[self.sBox replaceObjectAtIndex:i withObject:[self.sBox objectAtIndex:j]];
[self.sBox replaceObjectAtIndex:j withObject:tempObj];
}
//I'm calling in a different class by creating the RC4encryptor object
NSString *unescaped = [[RC4StringEncryptor encryptor] encrypt:#"10/28/2013"];
logDebug(#"the value is:%#",unescaped);
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
CFSTR("!*'();:#&=+$,/?%#[]\" "),
kCFStringEncodingUTF8));
NSLog(#"escapedString: %#",escapedString);
I've also tried
#import <CommonCrypto/CommonCryptor.h>
#implementation NSData (RC4)
- (NSData *)RC4EncryptWithKey:(NSString *)key {
char keyPtr[kCCKeySizeMinRC4+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCKeySizeMinRC4;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmRC4, kCCModeRC4,
keyPtr, kCCKeySizeMinRC4,
NULL ,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] RC4EncryptWithKey:key];
}
But this above code doesn't work for me.Kindly help me in this....

Somehow I fixed your code and it encrypts-decrypts perfectly. Here it is:
#interface RC4Crypt()
#property (nonatomic, strong) NSArray * key;
#property (nonatomic, strong) NSMutableArray * sBox;
#end
#implementation RC4Crypt
static const int SBOX_LENGTH = 256;
static const int KEY_MIN_LENGTH = 1;
-(NSString *)encrypt:(NSString *)string withKey:(NSString *)key{
self.sBox = [[self frameSBox:key] mutableCopy];
unichar code[string.length];
int i = 0;
int j = 0;
for (int n = 0; n < string.length; n++) {
i = (i + 1) % SBOX_LENGTH;
j = (j + [[self.sBox objectAtIndex:i]integerValue]) % SBOX_LENGTH;
[self.sBox exchangeObjectAtIndex:i withObjectAtIndex:j];
int index=([self.sBox[i] integerValue]+[self.sBox[j] integerValue]);
int rand=([self.sBox[(index%SBOX_LENGTH)] integerValue]);
code[n]=(rand ^ (int)[string characterAtIndex:n]);
}
const unichar* buffer;
buffer = code;
return [NSString stringWithCharacters:buffer length:string.length];
}
- (NSString*) decrypt:(NSString*)string withKey:(NSString*)key
{
return [self encrypt:string withKey:key];
}
-(NSArray *)frameSBox:(NSString *)keyValue{
NSMutableArray *sBox = [[NSMutableArray alloc] initWithCapacity:SBOX_LENGTH];
int j = 0;
for (int i = 0; i < SBOX_LENGTH; i++) {
[sBox addObject:[NSNumber numberWithInteger:i]];
}
for (int i = 0; i < SBOX_LENGTH; i++) {
j = (j + [sBox[i] integerValue] + [keyValue characterAtIndex:(i % keyValue.length)]) % SBOX_LENGTH;
[sBox exchangeObjectAtIndex:i withObjectAtIndex:j];
}
return [NSArray arrayWithArray:sBox];
}
#end

Related

Why am I getting wrong answer for this SPOJ Question

I still dont know weather I am allowed discuss Competetive Programming Doubts here, please let me know..
Can someone help me on this SPOJ question, I am getting wrong Answer:
https://www.spoj.com/problems/SPIKES/
I have tried all the test cases I could think of and the code always gives correct output.
Before posting it here, I also asked it in spoj forum but Its been two days, no one replies...
#include<bits/stdc++.h>
using namespace std;
// # = 35
// # = 64
// . = 46
// s = 115
// Using Dijkstra to find the path with minimum no. of Spikes
int n,m,j;
const int N = 100;
const int INF = 9;
vector<int> g[N];
int vis[N][N];
pair<int,int> dist[N][N];
vector<pair<int,int>> movements = {
{0,1},{0,-1},{1,0},{-1,0}
};
bool isvalid(int i, int j){
return i>=0 && j>=0 && i<n && j<m;
}
void bfs(int sourcei, int sourcej){
set<pair<int,pair<int,int>>> q;
q.insert({0,{sourcei,sourcej}});
dist[sourcei][sourcej] = {0,INF};
while(q.size()>0){
auto curr_v = *q.begin();
int curr_i = (curr_v.second).first;
int curr_j = (curr_v.second).second;
int spikes = curr_v.first;
q.erase(q.begin());
if(vis[curr_i][curr_j]) continue;
vis[curr_i][curr_j] = 1;
for(auto m : movements){
int child_i = curr_i + m.first;
int child_j = curr_j + m.second;
int spikec = spikes;
if(!isvalid(child_i,child_j)) continue;
if(g[child_i][child_j] == 115) spikec = spikes+1;
if(vis[child_i][child_j]) continue;
if(g[child_i][child_j]==35) continue;
if(dist[child_i][child_j].second > spikec){
dist[child_i][child_j] = {(dist[curr_i][curr_j].first +1),spikec};
q.insert({spikec , {child_i,child_j}});
}
}
}
}
int main(){
cin>>n>>m>>j;
int start_j,start_i;
int end_j,end_i;
for (int i = 0; i < N; ++i){
for (int j = 0; j < N; ++j){
dist[i][j].second = INF;
dist[i][j].first = 0;
}
}
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
char x; cin>>x;
g[i].push_back((int)x);
if(x=='#') {
start_i = i;
start_j = j;
}
if(x=='x'){
end_i = i;
end_j = j;
}
}
}
bfs(start_i,start_j);
// for (int i = 0; i < n; ++i){
// for (int j = 0; j < m; ++j){
// cout<<dist[i][j].first<<","<<dist[i][j].second<<" ";
// }cout<<endl;
// }
if(dist[end_i][end_j].second <= (int)j/2) cout<<"SUCCESS"<<endl;
else cout<<"IMPOSSIBLE"<<endl;
return 0;
}

Run-Time Check Failure #2 - Stack around the variable 'maxlong' was corrupted

I wrote a code to print the length of the longest line from my input and print out as much as possible of the longest line(There is a maximum length of what I can output the longest line). But I got this error. I tried everything I could yet still no clue. Is there anyone who might help?
#include<stdio.h>
#define MAXLINE 10
int getline(char line[], int len) {
int i,c,max;
i = 0;
max = 0;
while ((c = getchar()) != EOF&&c!='\n') {
if (i < len) {
line[i] = c;
}
i += 1;
}
if (i < len) {
if (c == '\n') {
line[i] = c;
i += 1;
}
line[i] = '\0';
}
else if (i >= len) {
line[len] = '\0';
}
return i;
}
void copy(char from[], char to[]) {
int i = 0;
while (from[i] != '\0') {
to[i] = from[i];
i += 1;
}
to[i] = '\0';
}
main() {
char longline[MAXLINE];
char longestline[MAXLINE];
char maxlong[MAXLINE];
int length;
int max = 0;
int maxline = 0;
while ((length = getline(longline, MAXLINE)) > 0) {
if (length > max && length < MAXLINE) {
copy(longline, longestline);
max = length;
}
else if (length > MAXLINE) {
if (length > maxline) {
maxline = length;
copy(longline, maxlong);
}
}
}
if (maxline == 0) {
printf("%s", longestline);
}
else {
printf("%s\n%d\n", maxlong, maxline);
}
}

aes cbc encrypt, decrypt result is diffrent(objecitve-c, c#)

i have a code in c# for aes decryption
i want make same encryption result by objective-c
but i failed.. help me
i can fix objective-c code, what can i for this?
c# for decrypt
private static readonly string AES_KEY = "asdfasdfasdfasdf";
private static readonly int BUFFER_SIZE = 1024 * 4;
private static readonly int KEY_SIZE = 128;
private static readonly int BLOCK_SIZE = 128;
static public string Composite(string value)
{
using (AesManaged aes = new AesManaged())
using (MemoryStream ims = new MemoryStream(Convert.FromBase64String(value), false))
{
aes.KeySize = KEY_SIZE;
aes.BlockSize = BLOCK_SIZE;
aes.Mode = CipherMode.CBC;
aes.Key = Encoding.UTF8.GetBytes(AES_KEY);
byte[] iv = new byte[aes.IV.Length];
ims.Read(iv, 0, iv.Length);
aes.IV = iv;
using (ICryptoTransform ce = aes.CreateDecryptor(aes.Key, aes.IV))
using (CryptoStream cs = new CryptoStream(ims, ce, CryptoStreamMode.Read))
using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Decompress))
using (MemoryStream oms = new MemoryStream())
{
byte[] buf = new byte[BUFFER_SIZE];
for (int size = ds.Read(buf, 0, buf.Length); size > 0; size = ds.Read(buf, 0, buf.Length))
{
oms.Write(buf, 0, size);
}
return Encoding.UTF8.GetString(oms.ToArray());
}
}
}
objective-c for encrypt
- (NSString *)AES128EncryptWithKey:(NSString *)key
{
NSData *plainData = [self dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedData = [plainData AES128EncryptWithKey:key];
NSString *encryptedString = [encryptedData stringUsingEncodingBase64];
return encryptedString;
}
#import "NSData+AESCrypt.h"
#import <CommonCrypto/CommonCryptor.h>
static char encodingTable[64] =
{
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
};
#implementation NSData (AESCrypt)
- (NSData *)AES128EncryptWithKey:(NSString *)key
{
// 'key' should be 16 bytes for AES128
char keyPtr[kCCKeySizeAES128 + 1]; // room for terminator (unused)
bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCModeCBC | kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted );
if( cryptStatus == kCCSuccess )
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free( buffer ); //free the buffer
return nil;
}
- (NSString *)base64Encoding
{
const unsigned char *bytes = [self bytes];
NSMutableString *result = [NSMutableString stringWithCapacity:self.length];
unsigned long ixtext = 0;
unsigned long lentext = self.length;
long ctremaining = 0;
unsigned char inbuf[3], outbuf[4];
unsigned short i = 0;
unsigned short charsonline = 0, ctcopy = 0;
unsigned long ix = 0;
while( YES )
{
ctremaining = lentext - ixtext;
if( ctremaining <= 0 ) break;
for( i = 0; i < 3; i++ )
{
ix = ixtext + i;
if( ix < lentext ) inbuf[i] = bytes[ix];
else inbuf [i] = 0;
}
outbuf [0] = (inbuf [0] & 0xFC) >> 2;
outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
outbuf [3] = inbuf [2] & 0x3F;
ctcopy = 4;
switch( ctremaining )
{
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for( i = 0; i < ctcopy; i++ )
[result appendFormat:#"%c", encodingTable[outbuf[i]]];
for( i = ctcopy; i < 4; i++ )
[result appendString:#"="];
ixtext += 3;
charsonline += 4;
}
return [NSString stringWithString:result];
}
------------------------------------------------------------
------------------------------------------------------------

How to separate two Low[1] by if statement?

Example, previous low is 1.55. When next candle low is 1.66, then next next candle low is 1.44 which is lower than previous low (1.55) then do something. How to achieve it?
double previous_low = 0;
double new_low = 0;
double new_low2 = 0;
if (((previous_low==0)&&(Low[1] < Low[2])){
previous_low = Low[1];
}
if (previous_low != 0){
if (Low[1] < previous_low){
new_low2 = Low[1]; //it fail
}
if (Low[0] < previous_low){
new_low2 = Low[0]; //it works only if next 1 candle is lower than previous. It fail if next 2 candle is lower than previous_low.
}
}
It can be achive by bubblesort
public class BubbleSort
{
void bubbleSort(double arr[])
{
int n = arr.length;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
{
System.out.print("first value :"+arr[j]+" greater than" +"previos :"+arr[j+1] + " ");
System.out.println();
// swap arr[j+1] and arr[i]
double temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
/* Prints the array */
void printArray(double arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver method to test above
public static void main(String args[])
{
BubbleSort ob = new BubbleSort();
double arr[] = {1.66, 1.55, 1.44};
ob.bubbleSort(arr);
System.out.println("Sorted array");
ob.printArray(arr);
}
}

Tarjan algorithm based on BFS

I have an implemented BFS algorithm and I want to find SCC with Tarjan's algorithm using my BFS (implemented with colors and time method). Here is the code: /////////////////////////////////////////////////////////////
void dfs_visit_color(int v, Graf *G, int *time)
{
time++;
G->d[v] = *time;
G->color[v] = GRI;
NodeT *p = G->t[v];
int w;
printf("%d ", v);
while (p != NULL)
{
w = p->val;
if (G->color[w] == ALB)
{
T[w] = v;
dfs_visit_color(w, G, time);
}
p = p->next;
}
G->color[v] = NEGRU;
time++;
G->f[v] = *time;
}
void dfs_color(Graf *G){
int time = 0, i;
for (i = 0; i < G->n; i++)
{
if (G->color[i] = ALB);
}
for (i = 0; i < G->n; i++)
{
if (G->color[i] == ALB)
{
dfs_visit_color(i, G, &time);
}
}
}

Resources