How to find maximum repeated characters in a string - string

I have a string "aaabbb".
Below program returned max repeated value as a.
But here in this case both a and b are max repeated characters.
How can I print that both a and b as max repeated characters.
import java.util.HashMap;
import java.util.Map.Entry;
class MaxRepeatedCharactersInString
{
public static void main(String[] args)
{
String s = "acakabbba";
HashMap<Character, Integer> map = new HashMap<>();
char[] ch = s.toCharArray();
for(char c : ch)
{
if(map.containsKey(c))
{
map.put(c, map.get(c)+1);
}
else
{
map.put(c, 1);
}
}
int maxCount = 0;
char maxChar = ' ';
System.out.println("Maximum repeated character in String: ");
for(Entry<Character, Integer> entry : map.entrySet())
{
if(maxCount < entry.getValue())
{
maxCount = entry.getValue();
maxChar = entry.getKey();
}
}
System.out.println(maxChar+"="+maxCount);
}
}

I added an extra Stack and a counter to store the maximum repeated characters
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Stack;
class MaxRepeatedCharactersInString {
public static void main(String[] args) {
String s = "aa";
HashMap<Character, Integer> map = new HashMap<>();
char[] ch = s.toCharArray();
for (char c : ch) {
if (map.containsKey(c)) {
map.put(c, map.get(c) + 1);
} else {
map.put(c, 1);
}
}
int maxCount = 0;
int noMax = 0;
Stack<Character> st = new Stack<>();
System.out.println("Maximum repeated characters in String: ");
for (Entry<Character, Integer> entry : map.entrySet()) {
if (maxCount < entry.getValue()) {
maxCount = entry.getValue();
noMax = 1;
st.push(entry.getKey());
} else if (maxCount == entry.getValue()) {
noMax++;
st.push(entry.getKey());
}
}
for (int i = 0; i < noMax; i++) {
System.out.println(st.pop() + "=" + maxCount);
}
}
}

Related

Implementing Undeniable Signature Scheme : random e1 and e2 failed to compute correct d in verify protocol

First you check undeniable signature scheme verifying algorithm.
Than in that there is first step telling to chose two random x1 and x2.
But the verifying algo works sometime and sometime failed depending on two randoms. ( algo implemented in java and correctly).
For the same input if we run that algo multiple time, sometime it signature is matched and sometime not, last comparison is failed.
Plz help me. Im stuck here ( lack of math).
Actually it is an signature scheme and in paper it was confusing but now i've figure out solution.
Solution code is: let me know if you need me to explain this code.
import java.lang.*;
import java.util.*;
import java.math.*;
import java.security.MessageDigest;
import java.nio.file.*;
import java.io.*;
import java.security.*;
class UndeniableSignature {
int Q; // prime
int P; // prime of form P = 2Q + 1
BigInteger G; // Generator of Z*P
int D; // private key belongs to [2 ... Q-1]
BigInteger Y; // G^D (mod P)
int invD; // D^-1 (mod Q)
Random rand = new SecureRandom(); // uniform random generator
public int[] extendedEuclidean(int a, int b) {
if(b==0) {
int[] arr=new int[3];
arr[0] = a;
arr[1] = 1;
arr[2] = 0;
return arr;
}
int[] subResult = extendedEuclidean(b,a%b);
int[] arr=new int[3];
arr[0] = subResult[0];
arr[1] = subResult[2];
arr[2] = subResult[1] - (a/b) * subResult[2];
return arr;
}
public int secureRandom(int max) {
return rand.nextInt(max);
}
public BigInteger getGenerator(BigInteger p, BigInteger q){
BigInteger generator = BigInteger.ZERO;
BigInteger exp = p.subtract(BigInteger.ONE).divide(q);
for(int i=2;i<p.intValue()-1;i++) {
generator = BigInteger.valueOf(i);
generator = generator.modPow(exp, p);
if(!generator.equals(BigInteger.ONE)) return generator;
}
// do {
// generator = BigInteger.valueOf(this.secureRandom(p.intValue()));
// generator = generator.modPow(exp, p);
// } while(generator.equals(BigInteger.ONE));
return generator;
// BigInteger generator = BigInteger.ZERO;
// for(long i = 2; i < p.intValue()-1; i++)
// {
// generator = BigInteger.valueOf(i);
// if(generator.modPow(BigInteger.valueOf(2), p).equals(BigInteger.ONE)) continue;
// if(generator.modPow(q, p).equals(BigInteger.ONE)) continue;
// else return generator;
// }
// return generator;
}
public String readMessageFile(String filename) {
try {
return new String(Files.readAllBytes(Paths.get(filename)));
} catch(Exception ex) {
System.out.println("ERR: Can't read file.");
}
return null;
}
public int[] readSignatureFile(String filename) {
InputStream is=null;
DataInputStream dis=null;
try {
is = new FileInputStream(filename);
dis = new DataInputStream(is);
ArrayList intList = new ArrayList();
int count = 0;
while(dis.available()>0) {
intList.add(dis.readInt());
}
int[] data = new int[intList.size()];
for(int i=0;i<data.length;i++) {
data[i] = (int)intList.get(i);
}
dis.close();
is.close();
return data;
} catch(Exception ex) {
System.out.println("ERR: Can't read file.");
}
return null;
}
public static void writeSignatureFile(String filename, int[] contents) {
FileOutputStream fos=null;
DataOutputStream dos=null;
try {
fos = new FileOutputStream(filename);
dos = new DataOutputStream(fos);
for(int i=0;i<contents.length;i++) {
dos.writeInt(contents[i]);
}
dos.flush();
dos.close();
fos.close();
} catch(Exception ex) {
System.out.println("ERR: Can't write to file.");
}
}
public void keyGeneration() {
System.out.println("UNDENIABLE SIGNATURE SCHEME");
System.out.println("- KEY GENERATION");
System.out.print("\tEnter prime P (such that P=2Q+1) : ");
this.P = new Scanner(System.in).nextInt();
this.Q = (this.P - 1)/2;
System.out.println("\tPrime Q is "+this.Q+".");
this.G = this.getGenerator(BigInteger.valueOf(this.P),BigInteger.valueOf(this.Q));
System.out.println("\tGenerator G of group Z*("+this.P+") is "+this.G+".");
System.out.print("\tEnter private key D (belongs to Z*P) :");
this.D = new Scanner(System.in).nextInt();
while(this.D <= 0 || this.D >= this.P) {
System.out.println("\tInvalid private key selected, please try again.");
System.out.print("\tEnter private key D (belongs to Z*P) :");
this.D = new Scanner(System.in).nextInt();
}
this.Y = this.G.modPow(BigInteger.valueOf(this.D), BigInteger.valueOf(this.P));
System.out.println("\tG^D(mod P) = "+this.Y+".");
System.out.println("\tPublic Key [P, G, Y] is ["+this.P+", "+this.G+", "+this.Y+"].");
System.out.println("\tPrivate Key [D] is ["+this.D+"].");
int[] g = this.extendedEuclidean(this.D, this.Q);
this.invD = g[1];
if(this.invD < 0) {
this.invD = this.Q - Math.abs(this.invD);
System.out.println("\tInverse was negative.");
}
System.out.println("\tInverse of D (mod Q) is "+this.invD+".");
}
public void messageSigning(String message) {
int[] signatureBytes = new int[message.length()];
for(int i=0;i<message.length();i++) {
BigInteger m = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger s = m.pow(this.D).mod(BigInteger.valueOf(this.P));
signatureBytes[i] = s.intValue();
// System.out.println("\tchar:"+message.charAt(i)+", m:"+m+", s:"+s+", S:"+signatureBytes[i]);
}
System.out.print("\tEnter signature filename : ");
String signatureFilename = new Scanner(System.in).nextLine();
this.writeSignatureFile(signatureFilename, signatureBytes);
System.out.println("\tSignature is successfully generated.");
}
// see the condition proof for w=W for solution of problem
public boolean signatureVerification(String message, int[] signature) {
for(int i=0;i<message.length();i++) {
// rand=new Random();
// int x1 = this.secureRandom(this.Q-1);
// while(x1<=1) x1 = this.secureRandom(this.Q-1);
// int x2 = this.secureRandom(this.Q-1);
// while(x2<=1) x2 = this.secureRandom(this.Q-1);
int x1 = 38, x2 = 397;
BigInteger S = BigInteger.valueOf(signature[i]);
BigInteger s = S.pow(x1);
BigInteger y = this.Y.pow(x2);
BigInteger z = s.multiply(y).mod(BigInteger.valueOf(this.P));
BigInteger w = signerChallengeForVerification(z);
BigInteger M = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger m = M.pow(x1);
BigInteger g = this.G.pow(x2);
BigInteger mg = m.multiply(g);
BigInteger W = mg.mod(BigInteger.valueOf(this.P));
// System.out.println("\ti:"+i+", char:"+message.charAt(i)+", m:"+M+", s:"+S);
// System.out.println("\t\tz:"+z+", w:"+w+" , W:"+W);
if(!w.equals(W)) {
return false;
}
}
return true;
}
public boolean disavowalProtocol(String message, int[] signature) {
int x1 = 38, x2 = 397;
BigInteger response1 = BigInteger.ZERO;
BigInteger response2 = BigInteger.ZERO;
// verification 1
for(int i=0;i<message.length();i++) {
BigInteger S = BigInteger.valueOf(signature[i]);
BigInteger s = S.pow(x1);
BigInteger y = this.Y.pow(x2);
BigInteger z = s.multiply(y).mod(BigInteger.valueOf(this.P));
BigInteger w = signerChallengeForVerification(z);
BigInteger M = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger m = M.pow(x1);
BigInteger g = this.G.pow(x2);
BigInteger mg = m.multiply(g);
BigInteger W = mg.mod(BigInteger.valueOf(this.P));
// System.out.println("\ti:"+i+", char:"+message.charAt(i)+", m:"+M+", s:"+S);
// System.out.println("\t\tz:"+z+", w:"+w+" , W:"+W);
if(!w.equals(W)) {
response1 = w;
break;
}
}
if(response1.equals(BigInteger.ZERO)) {
return false; // signature is not forgery bcoz signature is matched
}
// verification 2
for(int i=0;i<message.length();i++) {
BigInteger S = BigInteger.valueOf(signature[i]);
BigInteger s = S.pow(x1);
BigInteger y = this.Y.pow(x2);
BigInteger z = s.multiply(y).mod(BigInteger.valueOf(this.P));
BigInteger w = signerChallengeForVerification(z);
BigInteger M = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger m = M.pow(x1);
BigInteger g = this.G.pow(x2);
BigInteger mg = m.multiply(g);
BigInteger W = mg.mod(BigInteger.valueOf(this.P));
// System.out.println("\ti:"+i+", char:"+message.charAt(i)+", m:"+M+", s:"+S);
// System.out.println("\t\tz:"+z+", w:"+w+" , W:"+W);
if(!w.equals(W)) {
response2 = w;
break;
}
}
if(response2.equals(BigInteger.ZERO)) {
return false; // signature is not forgery bcoz signature is matched
}
// forgery validation now it comes here only when one of above validation is failed
BigInteger A = response1.divide(this.G.pow(x2)).pow(x1).mod(BigInteger.valueOf(this.P));
BigInteger B = response2.divide(this.G.pow(x1)).pow(x2).mod(BigInteger.valueOf(this.P));
return A.equals(B); // signature is forgery if A == B
}
public BigInteger signerChallengeForVerification(BigInteger z) {
// System.out.println("\tchallange: "+z+", invD:"+this.invD+", d:"+(z.pow(this.invD).mod(BigInteger.valueOf(this.P))));
return z.pow(this.invD).mod(BigInteger.valueOf(this.P));
}
}
class Program {
public static void main(String[] args) {
String msgFilename, signatureFilename, message;
UndeniableSignature scheme = new UndeniableSignature();
scheme.keyGeneration();
int choice = 0;
do {
System.out.println();
System.out.println("- OPERATIONS");
System.out.println("\t1. Sign message");
System.out.println("\t2. Verify signature");
System.out.println("\t3. Disavowal protocal");
System.out.println("\t4. Exit");
System.out.print("\tChoice : ");
choice = new Scanner(System.in).nextInt();
System.out.println();
switch(choice) {
case 1:
System.out.println("- MESSAGE SIGNING");
System.out.print("\tEnter message filename : ");
msgFilename = new Scanner(System.in).nextLine();
message = new String(scheme.readMessageFile(msgFilename));
scheme.messageSigning(message);
break;
case 2:
System.out.println("- SIGNATURE VERIFICATION");
System.out.print("\tEnter message filename : ");
msgFilename = new Scanner(System.in).nextLine();
System.out.print("\tEnter signature filename : ");
signatureFilename = new Scanner(System.in).nextLine();
message = scheme.readMessageFile(msgFilename);
int[] signatureBytes = scheme.readSignatureFile(signatureFilename);
if(scheme.signatureVerification(message, signatureBytes)) {
System.out.println("\tSignature IS valid.");
} else {
System.out.println("\tSignature is NOT valid.");
}
break;
case 3:
System.out.println("- DISAVOWAL VERIFICATION");
System.out.print("\tEnter message filename : ");
msgFilename = new Scanner(System.in).nextLine();
System.out.print("\tEnter signature filename : ");
signatureFilename = new Scanner(System.in).nextLine();
message = scheme.readMessageFile(msgFilename);
signatureBytes = scheme.readSignatureFile(signatureFilename);
if(scheme.disavowalProtocol(message, signatureBytes)) {
System.out.println("\tSignature IS forgery.");
} else {
System.out.println("\tSignature is NOT forgery.");
}
break;
case 4:
System.out.println("- BYE BYE");
break;
}
} while(choice!=4);
}
}
thanks :D

containsKey is returning true while expecting false

import java.util.HashMap;
public class Chapter1_Problem_1_1 {
public static void main(String[] args) {
String str = "bacdee";
int j = 0;
for(int i=0; i< str.length(); i++) {
char ch = str.charAt(i);
String s = new String(new char[] {ch});
HashMap<String, Integer> map = new HashMap<String, Integer>();
if (map.containsKey(s)) {
System.out.println("false");
} else {
map.put(s, j++);
System.out.println("true:: " + s);
}
}
}
}
In the above code, I am getting containskey as true for the last char "e" not sure why, it should be false; any ideas why this is happening?

How can I make int input to string input C#

How can I make int input to string input in C#? How can I change the int input to string input, so the user can write letters to the textbox, instead of numbers? I have tried myself, but the code won't work anymore. I know the solution is easy, but can't figure it out..
Here is my code:
public partial class MainWindow : Window
{
int[] arvat = new int[10];
int i = 0;
int k = 0;
public MainWindow()
{
InitializeComponent();
}
private void btnNimi_Click(object sender, RoutedEventArgs e)
{
int nimet = int.Parse( txtNimi.Text);
if (i < arvat.Length)
{
arvat[i] = nimet;
i++;
txtNimi.Text = "";
txtNimi.Focus();
}
else
{
MessageBox.Show("Kaikki arvat on syƶtetty.");
txtNimi.Text = "";
}
}
private void btnArpa_Click(object sender, RoutedEventArgs e)
{
int arpa = 0;
Random r = new Random();
arpa= r.Next(0, 9);
txbArvonta.Text = "";
for (int i = 0; i < arvat.Length; i++)
{
txbTeksti.Text = "\n" + "Kaikki osallistuneet: " + "\n";
txbArvonta.Text += arvat[i] + "\n";
int arpominen = arvat [k];
txbVoittaja.Text = "Ja voittaja on: " + arvat[arpa].ToString() + "\n" + "Onnea voittajalle!";
}
Instead of using Int.Parse, try using Int.TryParse to determine if the input will evaluate to a number before storing the result.
int number = 0;
bool isNumeric = Int32.TryParse(arvat[i], out number);
if (isNumeric)
{
Console.WriteLine("'{0}' is a number {1}.", arvat[i], number);
}
else
{
Console.WriteLine("'{0}' is text.", arvat[i]);
}

Algorithm for Hyper String

I want to know about the algorithm to solve HyperString Problem.
You can find the description at https://www.hackerrank.com/challenges/hyper-strings.
Can it be solved by dynamic programming?
Any help would be highly apreciated.
public class HyperString {
//Abubaker Tagelsir
private static int n,m,sum=1;
private static void temp(String u,String []d)
{
for(int i=0 ; i<d.length;i++)
{
if((u.length()+d[i].length())<=m)
{
sum++;
temp(u+d[i],d);
}
}
}
private static int Input3(String [] d)
{
sum +=d.length;
for(int i=0;i<d.length;i++){
for(int j=0;j<d.length;j++)
{
if((d[i].length()+d[j].length())<=m)
{
sum++;
temp(d[i]+d[j],d);
}
}
}
return sum;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String h = sc.nextLine();
StringTokenizer tz = new StringTokenizer(h);
String h1 = tz.nextToken();
n = Integer.parseInt(h1);
String h2 = tz.nextToken();
m = Integer.parseInt(h2);
//Input2();
String [] d = new String[n];
for(int i=0;i<n;i++)
{
d[i] = sc.nextLine();
}
System.out.println(Input3(d));
}
}

How to Install safari extension using setup project?

i have a working safari extension and i able to install it manually by dragging it on safari web browser. i want to know how can i install it programmatically.
i have done this for firefox, chrome and IE.
in firefox just copy your .xpi file to this folder ("C:\Users\admin\AppData\Roaming\Mozilla\Firefox\Profiles\xxx.default\extensions") in windows 7 and your extension will get installed.
and in chrome you have to write these registry keys
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Google\Chrome\Extensions\dlilbimladfdhkfbbcbjjnbleakbogef]
"version"="3.6"
"path"="C:\\extension.crx"
but in safari when i copy my .safariextz file to this folder "C:\Users\admin\AppData\Local\Apple Computer\Safari\Extensions" than extension not get installed.
can anybody guide me how can i do this.
In the folder:
~\Users\\AppData\Local\Apple Computer\Safari\Extensions
there is a file named Extensions.plist you will also need to add an entry for your extension in this file.
Extension.plist in "~\Users\AppData\Local\Apple Computer\Safari\Extensions" folder is a binary file. for read and add an entry we can use this class.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace PlistCS
{
public static class Plist
{
private static List<int> offsetTable = new List<int>();
private static List<byte> objectTable = new List<byte>();
private static int refCount;
private static int objRefSize;
private static int offsetByteSize;
private static long offsetTableOffset;
#region Public Functions
public static object readPlist(string path)
{
using (FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read))
{
return readPlist(f);
}
}
public static object readPlistSource(string source)
{
return readPlist(System.Text.Encoding.UTF8.GetBytes(source));
}
public static object readPlist(byte[] data)
{
return readPlist(new MemoryStream(data));
}
public static plistType getPlistType(Stream stream)
{
byte[] magicHeader = new byte[8];
stream.Read(magicHeader, 0, 8);
if (BitConverter.ToInt64(magicHeader, 0) == 3472403351741427810)
{
return plistType.Binary;
}
else
{
return plistType.Xml;
}
}
public static object readPlist(Stream stream, plistType type = plistType.Auto)
{
if (type == plistType.Auto)
{
type = getPlistType(stream);
stream.Seek(0, SeekOrigin.Begin);
}
if (type == plistType.Binary)
{
using (BinaryReader reader = new BinaryReader(stream))
{
byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
return readBinary(data);
}
}
else
{
using (BinaryReader reader = new BinaryReader(stream))
{
byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
return readBinary(data);
}
}
}
public static void writeBinary(object value, string path)
{
using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create)))
{
writer.Write(writeBinary(value));
}
}
public static void writeBinary(object value, Stream stream)
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(writeBinary(value));
}
}
public static byte[] writeBinary(object value)
{
offsetTable.Clear();
objectTable.Clear();
refCount = 0;
objRefSize = 0;
offsetByteSize = 0;
offsetTableOffset = 0;
//Do not count the root node, subtract by 1
int totalRefs = countObject(value) - 1;
refCount = totalRefs;
objRefSize = RegulateNullBytes(BitConverter.GetBytes(refCount)).Length;
composeBinary(value);
writeBinaryString("bplist00", false);
offsetTableOffset = (long)objectTable.Count;
offsetTable.Add(objectTable.Count - 8);
offsetByteSize = RegulateNullBytes(BitConverter.GetBytes(offsetTable[offsetTable.Count - 1])).Length;
List<byte> offsetBytes = new List<byte>();
offsetTable.Reverse();
for (int i = 0; i < offsetTable.Count; i++)
{
offsetTable[i] = objectTable.Count - offsetTable[i];
byte[] buffer = RegulateNullBytes(BitConverter.GetBytes(offsetTable[i]), offsetByteSize);
Array.Reverse(buffer);
offsetBytes.AddRange(buffer);
}
objectTable.AddRange(offsetBytes);
objectTable.AddRange(new byte[6]);
objectTable.Add(Convert.ToByte(offsetByteSize));
objectTable.Add(Convert.ToByte(objRefSize));
var a = BitConverter.GetBytes((long)totalRefs + 1);
Array.Reverse(a);
objectTable.AddRange(a);
objectTable.AddRange(BitConverter.GetBytes((long)0));
a = BitConverter.GetBytes(offsetTableOffset);
Array.Reverse(a);
objectTable.AddRange(a);
return objectTable.ToArray();
}
#endregion
#region Private Functions
private static object readBinary(byte[] data)
{
offsetTable.Clear();
List<byte> offsetTableBytes = new List<byte>();
objectTable.Clear();
refCount = 0;
objRefSize = 0;
offsetByteSize = 0;
offsetTableOffset = 0;
List<byte> bList = new List<byte>(data);
List<byte> trailer = bList.GetRange(bList.Count - 32, 32);
parseTrailer(trailer);
objectTable = bList.GetRange(0, (int)offsetTableOffset);
offsetTableBytes = bList.GetRange((int)offsetTableOffset, bList.Count - (int)offsetTableOffset - 32);
parseOffsetTable(offsetTableBytes);
return parseBinary(0);
}
private static int countObject(object value)
{
int count = 0;
switch (value.GetType().ToString())
{
case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
Dictionary<string, object> dict = (Dictionary<string, object>)value;
foreach (string key in dict.Keys)
{
count += countObject(dict[key]);
}
count += dict.Keys.Count;
count++;
break;
case "System.Collections.Generic.List`1[System.Object]":
List<object> list = (List<object>)value;
foreach (object obj in list)
{
count += countObject(obj);
}
count++;
break;
default:
count++;
break;
}
return count;
}
private static byte[] writeBinaryDictionary(Dictionary<string, object> dictionary)
{
List<byte> buffer = new List<byte>();
List<byte> header = new List<byte>();
List<int> refs = new List<int>();
for (int i = dictionary.Count - 1; i >= 0; i--)
{
var o = new object[dictionary.Count];
dictionary.Values.CopyTo(o, 0);
composeBinary(o[i]);
offsetTable.Add(objectTable.Count);
refs.Add(refCount);
refCount--;
}
for (int i = dictionary.Count - 1; i >= 0; i--)
{
var o = new string[dictionary.Count];
dictionary.Keys.CopyTo(o, 0);
composeBinary(o[i]);//);
offsetTable.Add(objectTable.Count);
refs.Add(refCount);
refCount--;
}
if (dictionary.Count < 15)
{
header.Add(Convert.ToByte(0xD0 | Convert.ToByte(dictionary.Count)));
}
else
{
header.Add(0xD0 | 0xf);
header.AddRange(writeBinaryInteger(dictionary.Count, false));
}
foreach (int val in refs)
{
byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
Array.Reverse(refBuffer);
buffer.InsertRange(0, refBuffer);
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] composeBinaryArray(List<object> objects)
{
List<byte> buffer = new List<byte>();
List<byte> header = new List<byte>();
List<int> refs = new List<int>();
for (int i = objects.Count - 1; i >= 0; i--)
{
composeBinary(objects[i]);
offsetTable.Add(objectTable.Count);
refs.Add(refCount);
refCount--;
}
if (objects.Count < 15)
{
header.Add(Convert.ToByte(0xA0 | Convert.ToByte(objects.Count)));
}
else
{
header.Add(0xA0 | 0xf);
header.AddRange(writeBinaryInteger(objects.Count, false));
}
foreach (int val in refs)
{
byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
Array.Reverse(refBuffer);
buffer.InsertRange(0, refBuffer);
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] composeBinary(object obj)
{
byte[] value;
switch (obj.GetType().ToString())
{
case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
value = writeBinaryDictionary((Dictionary<string, object>)obj);
return value;
case "System.Collections.Generic.List`1[System.Object]":
value = composeBinaryArray((List<object>)obj);
return value;
case "System.Byte[]":
value = writeBinaryByteArray((byte[])obj);
return value;
case "System.Double":
value = writeBinaryDouble((double)obj);
return value;
case "System.Int32":
value = writeBinaryInteger((int)obj, true);
return value;
case "System.String":
value = writeBinaryString((string)obj, true);
return value;
case "System.DateTime":
value = writeBinaryDate((DateTime)obj);
return value;
case "System.Boolean":
value = writeBinaryBool((bool)obj);
return value;
default:
return new byte[0];
}
}
public static byte[] writeBinaryDate(DateTime obj)
{
List<byte> buffer = new List<byte>(RegulateNullBytes(BitConverter.GetBytes(PlistDateConverter.ConvertToAppleTimeStamp(obj)), 8));
buffer.Reverse();
buffer.Insert(0, 0x33);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
public static byte[] writeBinaryBool(bool obj)
{
List<byte> buffer = new List<byte>(new byte[1] { (bool)obj ? (byte)9 : (byte)8 });
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryInteger(int value, bool write)
{
List<byte> buffer = new List<byte>(BitConverter.GetBytes((long)value));
buffer = new List<byte>(RegulateNullBytes(buffer.ToArray()));
while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
buffer.Add(0);
int header = 0x10 | (int)(Math.Log(buffer.Count) / Math.Log(2));
buffer.Reverse();
buffer.Insert(0, Convert.ToByte(header));
if (write)
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryDouble(double value)
{
List<byte> buffer = new List<byte>(RegulateNullBytes(BitConverter.GetBytes(value), 4));
while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
buffer.Add(0);
int header = 0x20 | (int)(Math.Log(buffer.Count) / Math.Log(2));
buffer.Reverse();
buffer.Insert(0, Convert.ToByte(header));
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryByteArray(byte[] value)
{
List<byte> buffer = new List<byte>(value);
List<byte> header = new List<byte>();
if (value.Length < 15)
{
header.Add(Convert.ToByte(0x40 | Convert.ToByte(value.Length)));
}
else
{
header.Add(0x40 | 0xf);
header.AddRange(writeBinaryInteger(buffer.Count, false));
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryString(string value, bool head)
{
List<byte> buffer = new List<byte>();
List<byte> header = new List<byte>();
foreach (char chr in value.ToCharArray())
buffer.Add(Convert.ToByte(chr));
if (head)
{
if (value.Length < 15)
{
header.Add(Convert.ToByte(0x50 | Convert.ToByte(value.Length)));
}
else
{
header.Add(0x50 | 0xf);
header.AddRange(writeBinaryInteger(buffer.Count, false));
}
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] RegulateNullBytes(byte[] value)
{
return RegulateNullBytes(value, 1);
}
private static byte[] RegulateNullBytes(byte[] value, int minBytes)
{
Array.Reverse(value);
List<byte> bytes = new List<byte>(value);
for (int i = 0; i < bytes.Count; i++)
{
if (bytes[i] == 0 && bytes.Count > minBytes)
{
bytes.Remove(bytes[i]);
i--;
}
else
break;
}
if (bytes.Count < minBytes)
{
int dist = minBytes - bytes.Count;
for (int i = 0; i < dist; i++)
bytes.Insert(0, 0);
}
value = bytes.ToArray();
Array.Reverse(value);
return value;
}
private static void parseTrailer(List<byte> trailer)
{
offsetByteSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(6, 1).ToArray(), 4), 0);
objRefSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(7, 1).ToArray(), 4), 0);
byte[] refCountBytes = trailer.GetRange(12, 4).ToArray();
Array.Reverse(refCountBytes);
refCount = BitConverter.ToInt32(refCountBytes, 0);
byte[] offsetTableOffsetBytes = trailer.GetRange(24, 8).ToArray();
Array.Reverse(offsetTableOffsetBytes);
offsetTableOffset = BitConverter.ToInt64(offsetTableOffsetBytes, 0);
}
private static void parseOffsetTable(List<byte> offsetTableBytes)
{
for (int i = 0; i < offsetTableBytes.Count; i += offsetByteSize)
{
byte[] buffer = offsetTableBytes.GetRange(i, offsetByteSize).ToArray();
Array.Reverse(buffer);
offsetTable.Add(BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0));
}
}
private static object parseBinaryDictionary(int objRef)
{
Dictionary<string, object> buffer = new Dictionary<string, object>();
List<int> refs = new List<int>();
int refCount = 0;
byte dictByte = objectTable[offsetTable[objRef]];
int refStartPosition;
refCount = getCount(offsetTable[objRef], out refStartPosition);
if (refCount < 15)
refStartPosition = offsetTable[objRef] + 1;
else
refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
for (int i = refStartPosition; i < refStartPosition + refCount * 2 * objRefSize; i += objRefSize)
{
byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
Array.Reverse(refBuffer);
refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
}
for (int i = 0; i < refCount; i++)
{
buffer.Add((string)parseBinary(refs[i]), parseBinary(refs[i + refCount]));
}
return buffer;
}
private static object parseBinaryArray(int objRef)
{
List<object> buffer = new List<object>();
List<int> refs = new List<int>();
int refCount = 0;
byte arrayByte = objectTable[offsetTable[objRef]];
int refStartPosition;
refCount = getCount(offsetTable[objRef], out refStartPosition);
if (refCount < 15)
refStartPosition = offsetTable[objRef] + 1;
else
//The following integer has a header aswell so we increase the refStartPosition by two to account for that.
refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
for (int i = refStartPosition; i < refStartPosition + refCount * objRefSize; i += objRefSize)
{
byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
Array.Reverse(refBuffer);
refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
}
for (int i = 0; i < refCount; i++)
{
buffer.Add(parseBinary(refs[i]));
}
return buffer;
}
private static int getCount(int bytePosition, out int newBytePosition)
{
byte headerByte = objectTable[bytePosition];
byte headerByteTrail = Convert.ToByte(headerByte & 0xf);
int count;
if (headerByteTrail < 15)
{
count = headerByteTrail;
newBytePosition = bytePosition + 1;
}
else
count = (int)parseBinaryInt(bytePosition + 1, out newBytePosition);
return count;
}
private static object parseBinary(int objRef)
{
byte header = objectTable[offsetTable[objRef]];
switch (header & 0xF0)
{
case 0:
{
//If the byte is
//0 return null
//9 return true
//8 return false
return (objectTable[offsetTable[objRef]] == 0) ? (object)null : ((objectTable[offsetTable[objRef]] == 9) ? true : false);
}
case 0x10:
{
return parseBinaryInt(offsetTable[objRef]);
}
case 0x20:
{
return parseBinaryReal(offsetTable[objRef]);
}
case 0x30:
{
return parseBinaryDate(offsetTable[objRef]);
}
case 0x40:
{
return parseBinaryByteArray(offsetTable[objRef]);
}
case 0x50://String ASCII
{
return parseBinaryAsciiString(offsetTable[objRef]);
}
case 0x60://String Unicode
{
return parseBinaryUnicodeString(offsetTable[objRef]);
}
case 0xD0:
{
return parseBinaryDictionary(objRef);
}
case 0xA0:
{
return parseBinaryArray(objRef);
}
}
throw new Exception("This type is not supported");
}
public static object parseBinaryDate(int headerPosition)
{
byte[] buffer = objectTable.GetRange(headerPosition + 1, 8).ToArray();
Array.Reverse(buffer);
double appleTime = BitConverter.ToDouble(buffer, 0);
DateTime result = PlistDateConverter.ConvertFromAppleTimeStamp(appleTime);
return result;
}
private static object parseBinaryInt(int headerPosition)
{
int output;
return parseBinaryInt(headerPosition, out output);
}
private static object parseBinaryInt(int headerPosition, out int newHeaderPosition)
{
byte header = objectTable[headerPosition];
int byteCount = (int)Math.Pow(2, header & 0xf);
byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
Array.Reverse(buffer);
//Add one to account for the header byte
newHeaderPosition = headerPosition + byteCount + 1;
return BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0);
}
private static object parseBinaryReal(int headerPosition)
{
byte header = objectTable[headerPosition];
int byteCount = (int)Math.Pow(2, header & 0xf);
byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
Array.Reverse(buffer);
return BitConverter.ToDouble(RegulateNullBytes(buffer, 8), 0);
}
private static object parseBinaryAsciiString(int headerPosition)
{
int charStartPosition;
int charCount = getCount(headerPosition, out charStartPosition);
var buffer = objectTable.GetRange(charStartPosition, charCount);
return buffer.Count > 0 ? Encoding.ASCII.GetString(buffer.ToArray()) : string.Empty;
}
private static object parseBinaryUnicodeString(int headerPosition)
{
int charStartPosition;
int charCount = getCount(headerPosition, out charStartPosition);
charCount = charCount * 2;
byte[] buffer = new byte[charCount];
byte one, two;
for (int i = 0; i < charCount; i += 2)
{
one = objectTable.GetRange(charStartPosition + i, 1)[0];
two = objectTable.GetRange(charStartPosition + i + 1, 1)[0];
if (BitConverter.IsLittleEndian)
{
buffer[i] = two;
buffer[i + 1] = one;
}
else
{
buffer[i] = one;
buffer[i + 1] = two;
}
}
return Encoding.Unicode.GetString(buffer);
}
private static object parseBinaryByteArray(int headerPosition)
{
int byteStartPosition;
int byteCount = getCount(headerPosition, out byteStartPosition);
return objectTable.GetRange(byteStartPosition, byteCount).ToArray();
}
#endregion
}
public enum plistType
{
Auto, Binary, Xml
}
public static class PlistDateConverter
{
public static long timeDifference = 978307200;
public static long GetAppleTime(long unixTime)
{
return unixTime - timeDifference;
}
public static long GetUnixTime(long appleTime)
{
return appleTime + timeDifference;
}
public static DateTime ConvertFromAppleTimeStamp(double timestamp)
{
DateTime origin = new DateTime(2001, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp);
}
public static double ConvertToAppleTimeStamp(DateTime date)
{
DateTime begin = new DateTime(2001, 1, 1, 0, 0, 0, 0);
TimeSpan diff = date - begin;
return Math.Floor(diff.TotalSeconds);
}
}
}
and use this method in commit action of Installer.cs class to add an entry of extension Extension.plist
public void InstallSafariExt()
{
string safariExtPlist = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\Extensions.plist";
string safariSetupPlist = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\YourComp\\YourSoft\\Extensions.plist";
string ExtDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions";
if (!Directory.Exists(ExtDir))
{
Directory.CreateDirectory(ExtDir);
if (!File.Exists(safariExtPlist))
{
File.Copy(safariSetupPlist, safariExtPlist);
}
}
else
{
if (!File.Exists(safariExtPlist))
{
File.Copy(safariSetupPlist, safariExtPlist);
}
}
object obj = Plist.readPlist(safariExtPlist);
Dictionary<string, object> dict = (Dictionary<string, object>)obj;
Dictionary<string, object> NewExt = new Dictionary<string, object>();
NewExt.Add("Hidden Bars", new List<object>());
NewExt.Add("Added Non-Default Toolbar Items", new List<object>());
NewExt.Add("Enabled", true);
NewExt.Add("Archive File Name", "YourExtName.safariextz");
NewExt.Add("Removed Default Toolbar Items", new List<object>());
NewExt.Add("Bundle Directory Name", "YourExtName.safariextension");
List<object> listExt = (List<object>)dict["Installed Extensions"];
listExt.Add(NewExt);
Plist.writeBinary(obj, safariExtPlist);
string safariExtFile = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\YourComp\\YourSoft\\YourExtName.safariextz";
string safariInstallfolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\YourExtName.safariextz";
string[] safExtFiles = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\", "YourExtName*.safariextz");
for (int i = 0; i < safExtFiles.Length; i++)
{
if (File.Exists(safExtFiles[i]))
File.Delete(safExtFiles[i]);
}
File.Copy(safariExtFile, safariInstallfolder);
}

Resources