Maven是管理和下载jar包的工具。
如何安装:
Open Eclipse IDE
Click Help -> Install New Software...
Click Add button at top right corner
At pop up: fill up Name as "M2Eclipse" and Location as "http://download.eclipse.org/technology/m2e/releases"
Now click OK
After that installation would be started.
Go to Window --> Preferences
Observe, Maven is enlisted at left panel
Finally,
项目配置
Click on an existing project
Select Configure -> Convert to Maven Project
Thursday, November 5, 2015
Monday, August 3, 2015
How to see websocket traffic in Chrome and Fiddler
Websocket是HTML5的一个重要功能,它让server和client端建立新的沟通channel, 让推送的功能更加快速。由于其省去每次发header这个步骤,测试表明websocket比Restful API要快三倍以上。不少网站已经开始使用websocket,比如six flags
这个网站可以测试websocket: https://www.websocket.org/echo.html
我们可以两个方法去看数据:
1. Google Chrome
Chrome在network tab可以看到这个websocket,frames可以看到data
2. Fiddler
在4.5版本中,可以加入额外的代码到custom js中:Rules > Customize Rules and add the following function inside your Handlers class,使得websocket数据显示在Log中:
这个网站可以测试websocket: https://www.websocket.org/echo.html
我们可以两个方法去看数据:
1. Google Chrome
Chrome在network tab可以看到这个websocket,frames可以看到data
在4.5版本中,可以加入额外的代码到custom js中:Rules > Customize Rules and add the following function inside your Handlers class,使得websocket数据显示在Log中:
static function OnWebSocketMessage(oMsg: WebSocketMessage) {
// Log Message to the LOG tab
FiddlerApplication.Log.LogString(oMsg.ToString());
/*
// Modify a message's content var sPayload = oMsg.PayloadAsString();
if (sPayload.Contains("time")) {
oMsg.SetPayload(sPayload + "... bazinga!");
}
*/
}
FiddlerApplication.Log.LogString(oMsg.ToString());
/*
// Modify a message's content var sPayload = oMsg.PayloadAsString();
if (sPayload.Contains("time")) {
oMsg.SetPayload(sPayload + "... bazinga!");
}
*/
}
Tuesday, July 21, 2015
Gmail API for C#
安装:
根据这个Quick start:https://developers.google.com/gmail/api/quickstart/dotnet
根据这个Quick start:https://developers.google.com/gmail/api/quickstart/dotnet
权限问题:
static string[] Scopes = { GmailService.Scope.GmailReadonly };
这句代码说明了权限只局限于Read email only,每次运行代码都会先检查权限文件C:\Users\KK\Documents\.credentials(自动生成,如果存在就会Cache)
如果要修改权限,比如改成
tatic string[] Scopes = { GmailService.Scope.GmailReadonly, GmailService.Scope.GmailModify, GmailService.Scope.GmailLabels};
运行代码前先要删除权限文件,因为默认下,它被cached了。
Thursday, June 4, 2015
Thursday, May 28, 2015
Introduction to Xcode
How to add images in Xcode:
New Group images(in fact it shows as a folder)->drag the images to that group->select "copy to destination" in the pop-up window
How to add a new tab to tab bar controller:
drag a view controller to the stroyboard->right click the tab bar controller->(鼠标在黑龙江后面那个点会出现add)add new view controller and connect it to the new controller by dragging a line.

Create a plist:
http://nscookbook.com/2013/02/ios-programming-recipe-13-using-property-lists-plists/

Tuesday, May 19, 2015
Android加密算法: java变成jar然后到dll
Android用定制的BouncyCastle (轻量级加密算法)并且去除key长度限制
1. Java AES encrypt example:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Encryptor {
public static String encrypt(String key1, String key2, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string:"
+ Base64.encodeBase64String(encrypted));
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String key1, String key2, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String key1 = "Bar12345Bar12345"; // 128 bit key
String key2 = "ThisIsASecretKet";
System.out.println(decrypt(key1, key2,
encrypt(key1, key2, "Hello World")));
}
}
2. JCE Unlimited Strength installation (java JCE download):
http://stackoverflow.com/questions/6363801/invalidkeyexception-illegal-key-size-java-code-throwing-exception-for-encryp
将local_policy.jar & US_export_policy.jar覆盖JRE security文件夹中的原始jar
3. How to export jar file in Eclipse (non-runnable jar):
if your code refers other libs, you need to copy the lib's source code in the src folder and compile together and can't use it as a jar reference.
Ref:
http://stackoverflow.com/questions/15554296/simple-java-aes-encrypt-decrypt-example
1. Java AES encrypt example:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Encryptor {
public static String encrypt(String key1, String key2, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string:"
+ Base64.encodeBase64String(encrypted));
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String key1, String key2, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String key1 = "Bar12345Bar12345"; // 128 bit key
String key2 = "ThisIsASecretKet";
System.out.println(decrypt(key1, key2,
encrypt(key1, key2, "Hello World")));
}
}
2. JCE Unlimited Strength installation (java JCE download):
http://stackoverflow.com/
将local_policy.jar & US_export_policy.jar覆盖JRE security文件夹中的原始jar
3. How to export jar file in Eclipse (non-runnable jar):
if your code refers other libs, you need to copy the lib's source code in the src folder and compile together and can't use it as a jar reference.
4. convert jar to dll/exe for .Net by ikvm:
Ref:
http://stackoverflow.com/
Sunday, May 17, 2015
singleton单例模式
顾名思义,就是一个class只能有一个instance。这是用得比较多的模式,场合主要是Util, database instance等。实现方法主要有两种:lazy initialization & eager initialization. 区别在于,eager总是产生一个新的instance.
public class SingletonDemo { private static SingletonDemo instance = null; private SingletonDemo() { } public static synchronized SingletonDemo getInstance() { if (instance == null) { instance = new SingletonDemo(); } return instance; } }
public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance() { return INSTANCE; } }
Factory method pattern工厂方法/abstract factory pattern抽象工厂
wiki提供的例子,工厂方法,是对单一产品(button)的异化,而抽象工厂是进一步的工厂方法或者是多个产品组合(工厂级别)的异化。
//几个Button类 class Button{/* ...*/} class WinButton extends Button{/* ...*/} class MacButton extends Button{/* ...*/} //它们的工厂类 interface ButtonFactory{ abstract Button createButton(); } class WinButtonFactory implements ButtonFactory{ Button createButton(){ return new WinButton(); } } class MacButtonFactory implements ButtonFactory{ Button createButton(){ return new MacButton(); } }
//几个Button类 class Button{/* ...*/} class WinButton extends Button{/* ...*/} class MacButton extends Button{/* ...*/} //它们的工厂类 interface ButtonFactory{ abstract Button createButton(); } class WinButtonFactory implements ButtonFactory{ Button createButton(){ return new WinButton(); } } class MacButtonFactory implements ButtonFactory{ Button createButton(){ return new MacButton(); } }
class Button; // Abstract Class class MacButton: public Button {}; class WinButton: public Button {}; class Border; // Abstract Class class MacBorder: public Border {}; class WinBorder: public Border {};
对应的工厂是这样的
class AbstractFactory { public: virtual Button* CreateButton() =0; virtual Border* CreateBorder() =0; }; class MacFactory: public AbstractFactory { public: MacButton* CreateButton() { return new MacButton; } MacBorder* CreateBorder() { return new MacBorder; } }; class WinFactory: public AbstractFactory { public: WinButton* CreateButton() { return new WinButton; } WinBorder* CreateBorder() { return new WinBorder; } };
Provider design pattern提供程序模式
提供程序模式是一个简单的模式,主要是为了减少代码复用而提高代码重用率而设计的模式,只在.Net框架中提供。ProviderBase是.Net提供的基础类. 它其实是继承的一种变体,从xml中读取各种继承的类的名字,从而一起调用一个基类方法实现不同类的同一行为。
下面是一个例子,用于得到不同酒店的价格。
public abstract class HotelProviderBase : ProviderBase
{
int RunId;
void setProxy(String proxy){}
public abstract void UpdateHotels(JobRequest request, int runId);
}
public sealed class ExampleHotelProvider : HotelProviderBase
{
private void UpdateHotel(JobRequest request){}
}
public abstract class HotelProviderManager
{
private static void LoadProviders()
{
//load class from hotel.xml
_providers = new HotelProviderCollection();
ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(HotelProviderBase));
}
}
public sealed class HotelManager
{
public void onRun()
{
foreach (HotelProviderBase provider in HotelProviderManager.Providers)
{
if (provider.Enabled)
{
provider.UpdateHotels(request, (int)Log.RunId);
}
}
}
}
hotel.xml
<add name="ExampleHotelProvider"
type="ExampleHotelProvider"
siteId="4"
siteName="http://www.example.com"
tableName="HotelRates_Example_Hotels">
http://www.cnblogs.com/webabcd/archive/2007/01/22/626479.html
下面是一个例子,用于得到不同酒店的价格。
public abstract class HotelProviderBase : ProviderBase
{
int RunId;
void setProxy(String proxy){}
public abstract void UpdateHotels(JobRequest request, int runId);
}
public sealed class ExampleHotelProvider : HotelProviderBase
{
private void UpdateHotel(JobRequest request){}
}
public abstract class HotelProviderManager
{
private static void LoadProviders()
{
//load class from hotel.xml
_providers = new HotelProviderCollection();
ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(HotelProviderBase));
}
}
public sealed class HotelManager
{
public void onRun()
{
foreach (HotelProviderBase provider in HotelProviderManager.Providers)
{
if (provider.Enabled)
{
provider.UpdateHotels(request, (int)Log.RunId);
}
}
}
}
hotel.xml
<add name="ExampleHotelProvider"
type="ExampleHotelProvider"
siteId="4"
siteName="http://www.example.com"
tableName="HotelRates_Example_Hotels">
http://www.cnblogs.com/webabcd/archive/2007/01/22/626479.html
命令模式Command pattern
由wiki里面的定义,命令模式是把action封装起来,方便重复使用。
下面演示一个测试android app基于UiAutomator的程序
1. EventInput: 首先定义event/command的输入参数
2. Events: 一系列的actions
3. Operator: 对应不同的input,invoke相应的action
4. Main class: 列出所有input, 然后operator开始做事
public abstract class EventInput {
public EventInput followingInput;
}
import java.util.ArrayList;
public class ClickEventInput extends EventInput{
protected String target;
//for GetListValues
public ClickEventInput(){}
public ClickEventInput(EventInput followingInput)
{
this.followingInput = followingInput;
}
public ClickEventInput(String target)
{
this(target,null);
}
public ClickEventInput(String target, EventInput followingInput)
{
this.target = target;
this.followingInput = followingInput;
}
}
public class Events {
protected static Operator op;
protected Events(Operator op)
{
this.op = op;
}
public void Click(UiDevice device, String buttonName, EventInput followingInput) throws UiObjectNotFoundException
{
try
{
if(new UiObject(new UiSelector().text(buttonName)).exists())
new UiObject(new UiSelector().text(buttonName)).clickAndWaitForNewWindow();
}
catch(Exception e)
{
Util.Log(3, "Can't press button", buttonName+","+e.toString());
return;
}
if(followingInput!=null)
op.InvokeAction(followingInput);
}
}
如果有其他行为,写custom类覆盖
public class CarEvents extends Events{
public CarEvents(Operator op) {
super(op);
}
public void Click(UiDevice device, String buttonName, EventInput followingInput) throws UiObjectNotFoundException
{
}
}
public class Operator{
UiDevice device;
EventInput input;
下面演示一个测试android app基于UiAutomator的程序
1. EventInput: 首先定义event/command的输入参数
2. Events: 一系列的actions
3. Operator: 对应不同的input,invoke相应的action
4. Main class: 列出所有input, 然后operator开始做事
public abstract class EventInput {
public EventInput followingInput;
}
import java.util.ArrayList;
public class ClickEventInput extends EventInput{
protected String target;
//for GetListValues
public ClickEventInput(){}
public ClickEventInput(EventInput followingInput)
{
this.followingInput = followingInput;
}
public ClickEventInput(String target)
{
this(target,null);
}
public ClickEventInput(String target, EventInput followingInput)
{
this.target = target;
this.followingInput = followingInput;
}
}
public class Events {
protected static Operator op;
protected Events(Operator op)
{
this.op = op;
}
public void Click(UiDevice device, String buttonName, EventInput followingInput) throws UiObjectNotFoundException
{
try
{
if(new UiObject(new UiSelector().text(buttonName)).exists())
new UiObject(new UiSelector().text(buttonName)).clickAndWaitForNewWindow();
}
catch(Exception e)
{
Util.Log(3, "Can't press button", buttonName+","+e.toString());
return;
}
if(followingInput!=null)
op.InvokeAction(followingInput);
}
}
如果有其他行为,写custom类覆盖
public class CarEvents extends Events{
public CarEvents(Operator op) {
super(op);
}
public void Click(UiDevice device, String buttonName, EventInput followingInput) throws UiObjectNotFoundException
{
}
}
public class Operator{
UiDevice device;
EventInput input;
public void InvokeAction(EventInput input)
{
Class cls = null;
Object value = false;
Class[] constructorArg = new Class[1];
constructorArg[0] = Operator.class;
Object obj = cls.getDeclaredConstructor(constructorArg).newInstance(this);
if(input instanceof ClickEventInput)
{
Method method = null;
Class[] cArg = new Class[3];
cArg[0] = UiDevice.class;
cArg[1] = String.class;
cArg[2] = EventInput.class;
ClickEventInput cInput = (ClickEventInput)input;
method = cls.getMethod("Click",cArg);
method.invoke(obj,device,cInput.target, input.followingInput);
}
}
}
public class NewCar extends UiAutomatorTestCase {
public void testDemo() throws UiObjectNotFoundException {
EventInput input = new ClickEventInput("MAKE & MODEL",,new SleepEventInput(3));
Operator op = new Operator(getUiDevice(), input,"Car", CarEvents.class);
op.Start();
}
}
Saturday, March 21, 2015
Postgres SQL
btim, length: (remove those records with invalid chars only like **()*%0_ )
select * from stocks
where length(btrim(description,' <>=*@_''-?%&()/":`.0'))>0
limit 10000
upper: (case sensitive)
select upper('aa')
replace:
replace('gary sham'.'sham','cen')
concatenate:
string||string
regex:
http://www.postgresql.org/docs/8.3/static/functions-matching.html
--remove price, g means replace all, no g means replace once
update aaa
set des = regexp_replace(des,E'\\$\s*[0-9,\\.]*','------------','g');
--get 1st blocks specified by regex
(regexp_matches(des,E'\\w+.*\\w+'))[1]
--get 5th separate blocks splitted by10+ dashes, regex for splitter
(regexp_split_to_array(des,E'\\-{10,}'))[5]
reverse:
https://wiki.postgresql.org/wiki/Reverse_string(supports only above 8.3)
data type:
http://www.postgresql.org/docs/9.3/static/datatype.html
string:
http://www.postgresql.org/docs/9.1/static/functions-string.html
operator:
http://www.postgresql.org/docs/6.3/static/c09.htm
vacuum space:
Vacuum city_table
Function:
call:
select run_proc()
define:
CREATE OR REPLACE FUNCTION run_proc() RETURNS void AS $func$
DECLARE
func_body text;
BEGIN
func_body := '
update descr d
set formatted_city=city
from loc c
where c.state=d.state' ;
EXECUTE func_body;
END;
$func$ LANGUAGE plpgsql;
Function example:
--drop FUNCTION singular2plural(input text)
create FUNCTION singular2plural(input text) RETURNS text
LANGUAGE plpgsql IMMUTABLE STRICT AS $$
DECLARE
result text = '';
root text;
suffix text = '';
pluralres text = '';
VOWELS text = 'aeiou';
BEGIN
IF btrim(length(btrim(input)))=0 then
return input;
END IF;
IF length(regexp_replace(btrim(input), E'(\\w+\\s*)*','','g'))>0 then
RAISE EXCEPTION 'singular2plural contains invalid character';
END IF;
SELECT plural INTO pluralres
FROM aa_aberrant_plural_map
WHERE singular = $1;
if pluralres<>'' then
return pluralres;
end if;
root = input;
if substring(input,length(input)) = 'y' AND strpos(VOWELS,substring(input,length(input)-1,1))=0 then
root = substring(input,1,length(input)-1);
suffix = 'ies';
elsif substring(input,length(input)) = 's' then
if strpos(VOWELS,substring(input,length(input)-2,1))>0 then
if substring(input,length(input)-3)='ius' then
root = substring(input,1,length(input)-2);
suffix = 'i';
else
root = substring(input,1,length(input)-1);
suffix = 'ses';
end if;
else
suffix = 'es';
end if;
elsif substring(input,length(input)-1)='ch' or substring(input,length(input)-1)='sh' then
suffix = 'es';
else suffix = 's';
end if;
result = root||suffix;
RETURN result;
END$$;
Function example:
drop FUNCTION if exists aa_sp_cat();
CREATE FUNCTION aa_sp_cat() RETURNS void AS $$
update q set city='New York' from cities c where cityid=5;
$$ LANGUAGE SQL;
Table options:
Create table products
(
productid integer,
desc varying_character
) with (Appendonly=true, compresslevel=5, orientation=column)
Distributed by (productid);
appendonly=can only insert records, no delete/update
orientation=separate table by columns
partition=separate table into bulks of rows
Distributed=physical storage key
productid integer,
desc varying_character
) with (Appendonly=true, compresslevel=5, orientation=column)
Distributed by (productid);
appendonly=can only insert records, no delete/update
orientation=separate table by columns
partition=separate table into bulks of rows
Distributed=physical storage key
Impot data from file using psql:
create table city_table
(
city character varying(100)
,stateabbr character varying(10)
)
1. Start psql with the following command: psql.exe -h 10.10.10.10 -d databasename
2. CTP_4M-> \copy public.city_table from C:\city.csv with csv header quote as '"'
in city.csv, column names: city, stateabbr
Thursday, March 5, 2015
HTTP POST简介
在研究postmates的API时候https://postmates.com/developer/docs要知道怎么用POST来得到数据
基本URL为https://api.postmates.com/v1/customers/:customer_id/delivery_quotes
API key和customer id从这里可以得到https://postmates.com/developer/testing
所以URL为https://api.postmates.com/v1/customers/cus_KEX15lMKh_770k/delivery_quotes
postmates提到
"Authentication is specified with HTTP Basic Authentication
POST data should be encoded as standard application/x-www-form-urlencoded
The Postmates API requires authentication by HTTP Basic Auth headers. Your API key should be included as the username. The password should be left empty."
Authorization(request header):
Basic access authentication(http://en.wikipedia.org/wiki/Basic_access_authentication)提到client side要a string "username:password"且用Base64加密后在前加上Basic+空格
d067ca26-7eb8-4dab-bebf-30ba3601e0f2:结果是
Authorization: Basic ZDA2N2NhMjYtN2ViOC00ZGFiLWJlYmYtMzBiYTM2MDFlMGYyOg==
Post data:
由上述理论提到post data要用form-urlencoded形式
在request header中加入
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
这个content type也决定了request body用http get的parameter形式name1=value1&name2=value2而不是json形式
request body:
pickup_address=165 Broadway, New York, NY&dropoff_address=2 gold st, New York, NY
在fiddler显示最后的结果为
返回结果:
基本URL为https://api.postmates.com/v1/customers/:customer_id/delivery_quotes
API key和customer id从这里可以得到https://postmates.com/developer/testing
所以URL为https://api.postmates.com/v1/customers/cus_KEX15lMKh_770k/delivery_quotes
postmates提到
"Authentication is specified with HTTP Basic Authentication
POST data should be encoded as standard application/x-www-form-urlencoded
The Postmates API requires authentication by HTTP Basic Auth headers. Your API key should be included as the username. The password should be left empty."
Authorization(request header):
Basic access authentication(http://en.wikipedia.org/wiki/Basic_access_authentication)提到client side要a string "username:password"且用Base64加密后在前加上Basic+空格
d067ca26-7eb8-4dab-bebf-30ba3601e0f2:结果是
Authorization: Basic ZDA2N2NhMjYtN2ViOC00ZGFiLWJlYmYtMzBiYTM2MDFlMGYyOg==
Post data:
由上述理论提到post data要用form-urlencoded形式
在request header中加入
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
这个content type也决定了request body用http get的parameter形式name1=value1&name2=value2而不是json形式
request body:
pickup_address=165 Broadway, New York, NY&dropoff_address=2 gold st, New York, NY
在fiddler显示最后的结果为
返回结果:
Thursday, February 5, 2015
用Fiddler捕捉phone的traffic
具体细节参看官网:http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/ConfigureForiOS
1. phone & 电脑连接同一个wifi
2. 获取电脑的IP地址, 并且输入到phone的wifi设置中,port 8888是fiddler默认的。

3. 在Fiddler中设置options->connections->Allow remote computers to connect以及安装Certificate Maker plugin。
4. 在Fiddler中设置options->HTTPS->Actions->Trust root certificate
5. iphone6以上还需要信任证书Settings -> General -> About -> Certificate Trust Settings。登录手机 浏览器,输入地址192.168.1.3:8888。如果看见Fiddler Echo Service说明成功。
6. 可选项:fiddler中设置或者HTTPS
此时我们可以见到fiddler开始捕捉手机上的traffic,当然电脑上的traffic也会捕捉,process可以区分出他们,chrome是来自电脑,空白的是来自phone
7. 如上图所示,有的traffic会显示tunnel to,表示这些request用了SSL,我们在手机安装一些证书来骗过这些网站从而获得细节
电脑中fiddler的网址是http://localhost:8888/ 证书也位于这里
在手机我们输入电脑的IP,port是8888,就可以访问该网址,如上述例子,我们在手机浏览器输入http://192.168.1.3:8888/ 我们见到一个hyperlink: you can download the Fiddler certificate
安装了之后,就可以看到这些traffic了,不过不是所有SSL都可以骗,比如twitter就不可以了。
要删除fiddler cert可以settting->general->profile(iphone)
重新安装Fiddler的话都要重新再手机上安装此证书,在iphone中,证书通过以上方法可能打开不了,可以在fiddler把证书下载下来Options->HTTPS->Actions->Export root cert to desktop然后通过邮件发到手机即可打开。
Android的配置:
http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/ConfigureForAndroid
另一个Post
1. phone & 电脑连接同一个wifi
2. 获取电脑的IP地址, 并且输入到phone的wifi设置中,port 8888是fiddler默认的。
3. 在Fiddler中设置options->connections->Allow remote computers to connect以及安装Certificate Maker plugin。
4. 在Fiddler中设置options->HTTPS->Actions->Trust root certificate
5. iphone6以上还需要信任证书Settings -> General -> About -> Certificate Trust Settings。登录手机 浏览器,输入地址192.168.1.3:8888。如果看见Fiddler Echo Service说明成功。
6. 可选项:fiddler中设置或者HTTPS
此时我们可以见到fiddler开始捕捉手机上的traffic,当然电脑上的traffic也会捕捉,process可以区分出他们,chrome是来自电脑,空白的是来自phone
7. 如上图所示,有的traffic会显示tunnel to,表示这些request用了SSL,我们在手机安装一些证书来骗过这些网站从而获得细节
电脑中fiddler的网址是http://localhost:8888/ 证书也位于这里
在手机我们输入电脑的IP,port是8888,就可以访问该网址,如上述例子,我们在手机浏览器输入http://192.168.1.3:8888/ 我们见到一个hyperlink: you can download the Fiddler certificate
安装了之后,就可以看到这些traffic了,不过不是所有SSL都可以骗,比如twitter就不可以了。
要删除fiddler cert可以settting->general->profile(iphone)
重新安装Fiddler的话都要重新再手机上安装此证书,在iphone中,证书通过以上方法可能打开不了,可以在fiddler把证书下载下来Options->HTTPS->Actions->Export root cert to desktop然后通过邮件发到手机即可打开。
Android的配置:
http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/ConfigureForAndroid
另一个Post
Monday, February 2, 2015
Selenium in C# - Browser Automation
OpenQA.Selenium:
Start: http://docs.seleniumhq.org/docs/03_webdriver.jsp
SetPreference: http://seleniumeasy.com/selenium-tutorials/firefox-profile-preferences-using-selenium-webdriver
FindElement(By): http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/By.html?_sm_au_=iVVsMF35HZfF7QWj
FirefoxProfile profile = new FirefoxProfile();
profile.SetPreference("network.proxy.http", "1234");
FirefoxDriver browser = new FirefoxDriver(profile);
browser.PageSource.Contains("abcd");
IWebElement total = browser.FindElement(By.ClassName("ddd"));//css class
String totalStr = total.Text;
ReadOnlyCollection<IWebElement> children = total.FindElements(By.ClassName("eee")).FindElement(By.ClassName("fff"));
foreach (IWebElement product in children){}
String innerHtml = total.GetAttribute("innerHTML");
total.Click();
//selelium's approach: scroll an element into view
browser.ExecuteJavaScript("arguments[0].scrollIntoView(true);", total);
xpath
("//div[@class='abc']")[1]
("//div[contains(@class, 'abc']")//h4[contains(text(), 'bb')]
Start: http://docs.seleniumhq.org/docs/03_webdriver.jsp
SetPreference: http://seleniumeasy.com/selenium-tutorials/firefox-profile-preferences-using-selenium-webdriver
FindElement(By): http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/By.html?_sm_au_=iVVsMF35HZfF7QWj
FirefoxProfile profile = new FirefoxProfile();
profile.SetPreference("network.proxy.http", "1234");
FirefoxDriver browser = new FirefoxDriver(profile);
browser.PageSource.Contains("abcd");
IWebElement total = browser.FindElement(By.ClassName("ddd"));//css class
String totalStr = total.Text;
ReadOnlyCollection<IWebElement> children = total.FindElements(By.ClassName("eee")).FindElement(By.ClassName("fff"));
foreach (IWebElement product in children){}
String innerHtml = total.GetAttribute("innerHTML");
total.Click();
//selelium's approach: scroll an element into view
browser.ExecuteJavaScript("arguments[0].scrollIntoView(true);", total);
xpath
("//div[@class='abc']")[1]
("//div[contains(@class, 'abc']")//h4[contains(text(), 'bb')]
KB: C#
AppSettingsReader:
Read app.config file
XmlDocument & XmlNode (Read XML file):
XmlDocument configDoc = new XmlDocument();
configDoc.Load(fileName);
XmlNode oneNode = configDoc.SelectSingleNode("//config/");
String abc = botNode.Attributes["proxy"];
Attribute & CustomAttributeData:
FieldInfo[] fs = obj.GetType().GetFields();
foreach (FieldInfo f in fs)
{
IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(f);
foreach (CustomAttributeData attribute in attributes)
{
//check if the field was marked as [ConfigValue]
if (attribute.Constructor.DeclaringType.Equals(typeof(ConfigValue)))
{}
}
}
[AttributeUsage(AttributeTargets.Field)]
public class ConfigValue : Attribute
{
private String prameName;
public ConfigValue(String name)
{
prameName = name;
}
}
[AttributeUsage(AttributeTargets.Field)]
public class RegexFile : Attribute
{
private String fileName;
public RegexFile(String name)
{
fileName = name;
}
}
Use:
[ConfigValue]
String proxy;
[RegexFile("rabc.regex")]
private Regex rabc;
Read app.config file
XmlDocument & XmlNode (Read XML file):
XmlDocument configDoc = new XmlDocument();
configDoc.Load(fileName);
XmlNode oneNode = configDoc.SelectSingleNode("//config/");
String abc = botNode.Attributes["proxy"];
Attribute & CustomAttributeData:
FieldInfo[] fs = obj.GetType().GetFields();
foreach (FieldInfo f in fs)
{
IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(f);
foreach (CustomAttributeData attribute in attributes)
{
//check if the field was marked as [ConfigValue]
if (attribute.Constructor.DeclaringType.Equals(typeof(ConfigValue)))
{}
}
}
[AttributeUsage(AttributeTargets.Field)]
public class ConfigValue : Attribute
{
private String prameName;
public ConfigValue(String name)
{
prameName = name;
}
}
[AttributeUsage(AttributeTargets.Field)]
public class RegexFile : Attribute
{
private String fileName;
public RegexFile(String name)
{
fileName = name;
}
}
Use:
[ConfigValue]
String proxy;
[RegexFile("rabc.regex")]
private Regex rabc;
Friday, January 16, 2015
KB: VB
VBScript:
aa.bat:
rem wscript abc.vbs male
cscript abc.vbs male
abc.vbs:
set wnet =CreateObject("WScript.Network")
uname=wnet.UserName
uage = InputBox("Please enter your age")
gender = WScript.Arguments(0)
MsgBox "Your user name is " & uname & "," & uage & "," & gender
Friday, January 2, 2015
Publish your Android app
1. Generate key
http://www.apkbus.com/android-44559-1-1.html
2. Go to Google Play Developer page to publish the app (registration fee $25 for lifetime)
Ref:
http://developer.android.com/distribute/index.html
http://mobile.51cto.com/android-228966_all.htm
Subscribe to:
Posts (Atom)