Oracle DB의 LONGRAW 필드에 binary EXE 또는 Image 등을 업로드 해 놓고 Client의 Program 실행시에
버전을 검사하여 하위버전인 경우 다운로드 하도록 하는 프로그램.
업무구분에 따라 경로가 고정되어 있었으나 경로의 복잡성이 추가되어
파일이름에 경로를 붙여 사용하도록 협의되어 일부 수정되었다.
SetPointer(HourGlass!)
/* Transaction Connection */
File_Tran = Create Transaction
File_Tran.dbms = dbms
File_Tran.logid = userid
File_Tran.logpass = passwd
File_Tran.servername = servername
Connect Using File_Tran;
If File_Tran.sqlcode <> 0 Then
MessageBox ("확인",' 데이터베이스 연결 실패입니다.')
Halt Close
Return
End If
/* 선언부 */
String FileName, Version_PC, FileStyle
String RootPath, FullPath, EtcPath, FilePath, IniPath, ExePath
String ConnectParm
Boolean lb_Check = False
Integer li_I, FP , Loops, li_Complete, Version_SR
Long FLen = 0, bytes_Read = 0, Start_Pos = 0, Next_Pos = 0
Blob ImageData, Blob_Chunk
/* PC 에서 최초 실행시 각 사용자별 디렉토리 생성 */
RootPath = 'c:\program' // 기본 디렉토리
FullPath = RootPath + '\' + gs_UserID //------ 실행 화일관리
EtcPath = FullPath + '\' + 'etc' //------ 기타화일 관리
/* 화일 저장 디렉토리 생성 */
If FileExists(RootPath) Then
If FileExists(FullPath) Then
If FileExists(EtcPath) = False Then
CreateDirectoryA(EtcPath,0)
End If
Else
CreateDirectoryA(FullPath,0)
CreateDirectoryA(EtcPath,0)
End If
Else
CreateDirectoryA(RootPath,0)
CreateDirectoryA(FullPath,0)
CreateDirectoryA(EtcPath,0)
End If
/* 각 단위 업무 수정사항 조회 */
DECLARE Cur_File CURSOR FOR
SELECT VER_FILENAME, VER_VERSION, VER_EXT_STYLE
FROM CLSM_VER11_PROGRAM
WHERE VER_UPMUCODE = :gs_JobGubun OR
VER_UPMUCODE = 'S'
ORDER BY VER_FILENAME ASC using File_Tran;
OPEN Cur_File;
FETCH Cur_File INTO :FileName, :Version_SR, :FileStyle;
/* 화일 버전 체크 위항 ini 화일 체크하고 생성 */
IniPath = FullPath + '\' + gs_UserID + '.ini'
wf_Write_ini(IniPath, gs_UserID)
// 2010. 11. 6 수정
// dwis 추가로 Filename에 경로를 붙여 처리하도록 수정
//-----------------------------------------------------------------------------------------------------
String ls_full_name = ""
String ls_split_name = ""
String ls_target_path = ""
integer li_root_pos
DO WHILE File_Tran.SQLCode = 0
//-----------------------------------------------------------------------------------------------------
// 저장할 경로가 존재하는지 검사 : 없으면 새로 만듦
//-----------------------------------------------------------------------------------------------------
ls_full_name = FileName
// 먼저 파일명을 제외한 패스가 존재하는지 부터 점검
ls_target_path = midA(ls_full_name, 1, Len(ls_full_name) - Pos(Reverse(ls_full_name), "\"))
ls_split_name = ""
// 없으면 아래를 실행
If Not FileExists(ls_target_path) Then
DO while(true)
li_root_pos = pos(ls_full_name, "\")
// 마지막 자료는(\가 없음) Skip << 파일이름
IF li_root_pos < 1 THEN
EXIT
END IF
If ls_split_name = "" then
ls_split_name += midA(ls_full_name, 1, li_root_pos - 1)
else
ls_split_name += "\" + midA(ls_full_name, 1, li_root_pos - 1)
end if
ls_full_name = midA(ls_full_name, li_root_pos + 1)
// 드라이브 문자열만 들어올 경우 Skip (ex: c:, d: << \ 기호가 없음)
If pos(ls_split_name, "\") > 0 Then
// 경로가 없을 경우 생성
If Not FileExists(ls_split_name) Then
CreateDirectoryA(ls_split_name,0)
End If
End If
LOOP
End If
//-----------------------------------------------------------------------------------------------------
Version_PC = ProfileString(IniPath, FileName, 'FileVersion', "X")
If (Version_SR <> Integer(Version_PC)) OR Version_PC = 'X' Then
If lb_Check = False Then
// 다운 받고 있을때의 Animation //
This.Title = '화일 내려받는 중 '
DelAnim()
Trigger Event ue_animation()
lb_Check = True
End If
uo_1.uf_setvisible(0)
st_filename.Text = FileName
SELECTBLOB VER_FILESOURCE
INTO :ImageData
FROM CLSM_VER11_PROGRAM
WHERE VER_FILENAME = :FileName AND
(VER_UPMUCODE= :gs_jobgubun OR
VER_UPMUCODE= 'S' )
using File_Tran ;
IF File_Tran.Sqlcode <> 0 THEN
DisConnect Using File_Tran;
DelAnim()
Halt Close
Return
End If
//-----------------------------------------------------------------------------------------------------
// 파일 이름에 \이 포함된경우 이름 그대로 경로처리 : 추가
If Pos(FileName, "\") > 0 Then
FilePath = FileName
Else
// 기존 처리 방식
/* 실행화일과 PBD 이외의 화일은 BMP 디렉토리에 관리 */
If Upper(FileStyle) = 'EXE' OR Upper(FileStyle) = 'PBD' Then
FilePath = FullPath + '\' + FileName
ElseIf Upper(FileStyle) = 'BMP' Then
FilePath = RootPath + '\install\bmp\' + FileName
ElseIf Upper(FileStyle) = 'DLL' Then
FilePath = RootPath + '\install\lib\' + FileName
Else
FilePath = EtcPath + '\' + FileName
End If
End If
//-----------------------------------------------------------------------------------------------------
FP = FileOpen(FilePath, StreamMode!, Write!,LockWrite!, replace!)
///// **** 화일 변수 책정 초기화 **** ///////
Next_Pos = 1; Loops = 0; FLen = 0
IF FP <> 0 then
Flen = Len(ImageData)
st_size.Text = String(FLen,'#,###,###')
If FLen > 32765 Then
If Mod(FLen,32765) = 0 Then
Loops = FLen/32765
Else
Loops = (FLen/32765) + 1
End If
Else
Loops = 1
End If
If Loops = 1 Then
Bytes_Read = FileWrite(FP,ImageData)
uo_1.uf_setvisible(100)
Else
For li_I = 1 To Loops
li_Complete = ( (32765 * li_I ) / Len(ImageData)) * 100
uo_1.uf_setvisible(li_Complete)
If li_I = Loops Then
Blob_Chunk = BlobMid(ImageData,Next_Pos)
Else
Blob_Chunk = BlobMid(ImageData,Next_Pos,32765)
End If
Bytes_Read = FileWrite(FP, Blob_Chunk)
Next_Pos = Next_Pos + Bytes_Read
Next
End If
FileClose(FP)
///// 차후 화일 다운 받기 위한 초기화 화일 /////
SetProfileString(IniPath, FileName, 'FileVersion', String(Version_SR))
End If
End If
FileName = ''; Version_PC = '';
FETCH Cur_File INTO :FileName, :Version_SR, :FileStyle;
LOOP
CLOSE Cur_File;
/* 실행 화일 넘겨질 변수 설정 */
ConnectParm = gs_UserID + '/' + gs_UserPassWD + '/' + dbms + '/' + servername +&
'/' + gs_Jobgubun + '/' + gs_Sabun + '/' + gs_Passwd + '/' + '' + '/'
ExePath = FullPath + '\' + gs_UserID + '.exe '
If FileExists(ExePath) = False Then
DisConnect Using File_Tran;
MessageBox("확인", '당 업무 해당 실행화일이 없습니다. 프로그램을 종료하겠습니다.'&
,StopSign!)
Halt Close
Return
End If
Close(This)
Close(w_jobbmp_display)
//각 단위 업무 화일 실행 //
Run(ExePath + ConnectParm)
2010년 11월 5일 금요일
ASP.NET에서 다른컴퓨터의 폴더 Access
web.config의 <system.web> 내부에 다음 항목 추가
<identity impersonate="true" userName="사용자계정" password="암호" />
폴더를 Access할때 위 계정정보를 사용하여 Access함.
당연히, 해당 컴퓨터에 사용자 정보를 만들어 줘야함
<identity impersonate="true" userName="사용자계정" password="암호" />
폴더를 Access할때 위 계정정보를 사용하여 Access함.
당연히, 해당 컴퓨터에 사용자 정보를 만들어 줘야함
OCR 인식 테스트 : MS Officce Document Imaging : 배율확대에 의한 인식율
MS Office Document Imaging의 OCR 인식 기능을 사용하여 숫자만 가득한 이미지를 테스트 해 보았다.
인식이 잘 되는 경우도 있고 안되는 경우도 있어서 이미지를 단계별로 확대해 가며 정확하게 읽어지는지 검사했다.
주로 1.4배~1.7배 사이에서 인식이 잘 되는것 같긴 한데..
이미지에 따라 인식율이 다르게 나온다.
더 나은 OCR 라이브러리가 필요할듯...
1x 115440 4,285 4,260 4.320 4,260 4 290 4,930 3,650 3,660 15 4.. 260 1 090
1.1x 115440 4285 4,260 4,320 4,260 4, 290 4,930 3650 3,660 15 4, 261) 1 .fl
1.2x 115440 4,285 4,260 4,320 4260 4,290 4,930 3,650 3,660 15 4,260 1 .090
1.3x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 I L LJJ L090
1.4x 115440 4.285 4.260 4.320 4.260 4.2% 4.930 3.650 3.660 15 4.260 1.090
1.5x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1090
1.5x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1090 24bit
1.6x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1,090 *****
1.7x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1,090
1.8x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 L090
1.9x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1,090
2x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 I_I, ? 15 4,260 1,090
3x p _ C) N) 0, CDN)N)C)N) CD 0, 0, C) CD 0, N) 0, C) 0, (1 p p (T
* 정규식
[0-9]{5,6}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}
인식이 잘 되는 경우도 있고 안되는 경우도 있어서 이미지를 단계별로 확대해 가며 정확하게 읽어지는지 검사했다.
주로 1.4배~1.7배 사이에서 인식이 잘 되는것 같긴 한데..
이미지에 따라 인식율이 다르게 나온다.
더 나은 OCR 라이브러리가 필요할듯...
1x 115440 4,285 4,260 4.320 4,260 4 290 4,930 3,650 3,660 15 4.. 260 1 090
1.1x 115440 4285 4,260 4,320 4,260 4, 290 4,930 3650 3,660 15 4, 261) 1 .fl
1.2x 115440 4,285 4,260 4,320 4260 4,290 4,930 3,650 3,660 15 4,260 1 .090
1.3x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 I L LJJ L090
1.4x 115440 4.285 4.260 4.320 4.260 4.2% 4.930 3.650 3.660 15 4.260 1.090
1.5x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1090
1.5x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1090 24bit
1.6x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1,090 *****
1.7x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1,090
1.8x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 L090
1.9x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 3,660 15 4,260 1,090
2x 115440 4,285 4,260 4,320 4,260 4,290 4,930 3,650 I_I, ? 15 4,260 1,090
3x p _ C) N) 0, CDN)N)C)N) CD 0, 0, C) CD 0, N) 0, C) 0, (1 p p (T
* 정규식
[0-9]{5,6}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}\s+[\,\.0-9]{2,10}
C#에서 MD5 암호화 사용
public string GetMD5Hash(string input)
{
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = System.Text.Encoding.UTF8.GetBytes(input);
bs = x.ComputeHash(bs);
System.Text.StringBuilder s = new System.Text.StringBuilder();
foreach (byte b in bs)
{
s.Append(b.ToString("x2").ToLower());
}
string password = s.ToString();
return password;
}
Rijndael(AES) 암/복호화 코드(C#)
AES는 미국 정부에서 민감한 정보들을 암호화하는 데 사용되는 표준 암/복호화 알고리즘입니다. 현재 업계 표준이고, 아직까지는 알려진 약점이 없는 가장 안전한 암/복호화 알고리즘입니다. 최근에 일부 SI 프로젝트에서는 이 방식을 꼭 쓸 것을 요구하기도 합니다.
1. 암호화
private static string EncryptString(string InputText, string Password)
{
// Rihndael class를 선언하고, 초기화 합니다
RijndaelManaged RijndaelCipher = new RijndaelManaged();
// 입력받은 문자열을 바이트 배열로 변환
byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(InputText);
// 딕셔너리 공격을 대비해서 키를 더 풀기 어렵게 만들기 위해서
// Salt를 사용합니다.
byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
// PasswordDeriveBytes 클래스를 사용해서 SecretKey를 얻습니다.
PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
// Create a encryptor from the existing SecretKey bytes.
// encryptor 객체를 SecretKey로부터 만듭니다.
// Secret Key에는 32바이트
// (Rijndael의 디폴트인 256bit가 바로 32바이트입니다)를 사용하고,
// Initialization Vector로 16바이트
// (역시 디폴트인 128비트가 바로 16바이트입니다)를 사용합니다
ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
// 메모리스트림 객체를 선언,초기화
MemoryStream memoryStream = new MemoryStream();
// CryptoStream객체를 암호화된 데이터를 쓰기 위한 용도로 선언
CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
// 암호화 프로세스가 진행됩니다.
cryptoStream.Write(PlainText, 0, PlainText.Length);
// 암호화 종료
cryptoStream.FlushFinalBlock();
// 암호화된 데이터를 바이트 배열로 담습니다.
byte[] CipherBytes = memoryStream.ToArray();
// 스트림 해제
memoryStream.Close();
cryptoStream.Close();
// 암호화된 데이터를 Base64 인코딩된 문자열로 변환합니다.
string EncryptedData = Convert.ToBase64String(CipherBytes);
// 최종 결과를 리턴
return EncryptedData;
}
2. 복호화
private static string DecryptString(string InputText, string Password)
{
RijndaelManaged RijndaelCipher = new RijndaelManaged();
byte[] EncryptedData = Convert.FromBase64String(InputText);
byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
// Decryptor 객체를 만듭니다.
ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
MemoryStream memoryStream = new MemoryStream(EncryptedData);
// 데이터 읽기(복호화이므로) 용도로 cryptoStream객체를 선언, 초기화
CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
// 복호화된 데이터를 담을 바이트 배열을 선언합니다.
// 길이는 알 수 없지만, 일단 복호화되기 전의 데이터의 길이보다는
// 길지 않을 것이기 때문에 그 길이로 선언합니다
byte[] PlainText = new byte[EncryptedData.Length];
// 복호화 시작
int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);
memoryStream.Close();
cryptoStream.Close();
// 복호화된 데이터를 문자열로 바꿉니다.
string DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);
// 최종 결과 리턴
return DecryptedData;
}
피드 구독하기:
글 (Atom)