암호에서 비밀번호를 사용할때, 해시함수를 사용한다.


 해시 함수는 단방향(일방적)인 암호방식을 사용할때, 혹은 암호문과 메세지의 변동이 있는지의 유무를 확인할 수 있다.


 보통은 비밀번호에 사용한다.(그리고 해시함수를 이용하면, 파일이 깨졌는지의 유무도 확인 할 수 있다.)


 해시란, 특정 덩어리를 특정 크기만큼으로 줄이는 방식을 뜻하는데. 압축이랑은 별개로 해당 값(해시 값)이 특정 덩어리를 뜻하긴 하지만, 해시 값으론 특정 덩어리를 알 수 없게 되어 있어서 압축과는 다르다.(압축은 압축한 대상이 특정 덩어리로 변환 될 수 있는 양방향성을 띈다.)


 여기서 유명한 SHA256을 사용할려고 한다.(필자는 SHA256을 이용해서 파일의 깨짐 유무를 확인할때 사용하기도 한다.)


 KISA에서 소스를 제공해주기도 한다.


 링크  : https://seed.kisa.or.kr/iwt/ko/bbs/EgovReferenceDetail.do?bbsId=BBSMSTR_000000000002&nttId=79


 외국에서는 C++로 객체화 해서 만들어져 있다.


 링크 : http://www.zedwood.com/article/cpp-sha256-function



소스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "KISA_SHA256.h"
 
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
 
int main(int argc, char** argv)
{
 
    //변수 초기화.
    FILE *fp = NULL;
    unsigned char buffer[2048= { 0, };
    unsigned char result[32= { 0, };
    int read = 0;
    int loop_number = 0;
 
    //SHA256 변수 초기화.
    SHA256_INFO sha256_info;
 
    SHA256_Init(&sha256_info);
 
    //파일 읽기.
    //fp = fopen("Test.txt", "rb"); Visual Studio 옛버전을 사용할 경우. 이것을 사용할 것. Visual Studio에서 안전성 문제로 인한 함수 개선을 하였음.
    fopen_s(&fp, "Text.txt""rb");
 
    if (fp == NULL)
    {
        printf("Error : File not find.\n");
        system("pause");
        return -1;
    }
 
    while ((read = fread(buffer, 20481, fp)) != 0)
    {
        SHA256_Process(&sha256_info, buffer, read);
    }
 
    SHA256_Close(&sha256_info, result);
 
    for (loop_number = 0; loop_number < 32; loop_number++)
    {
        printf("%02x", result[loop_number]);
    }
 
    system("pause");
    return 0;
 
}
 
cs


Posted by JunkMam
,


 참조 링크 : http://forums.codeguru.com/showthread.php?263490-C-Source-For-Ejecting-CD-ROM


 설정하는 참조 링크에 존재하는 소스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
 
#define LOCK_TIMEOUT  10000       // 10 Seconds
#define LOCK_RETRIES  20
 
HANDLE OpenVolume(TCHAR cDriveLetter)
{
    HANDLE hVolume;
    UINT   uDriveType;
    char   szVolumeName[8];
    char   szRootName[5];
    DWORD  dwAccessFlags;
   
    sprintf(szRootName, "%c:\\", cDriveLetter);
 
    uDriveType = GetDriveType(szRootName);
    switch(uDriveType) {
      case DRIVE_REMOVABLE:
           dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
           break;
      case DRIVE_CDROM:
           dwAccessFlags = GENERIC_READ;
           break;
      default:
           printf("Cannot eject.  Drive type is incorrect.\n");
           return INVALID_HANDLE_VALUE;
    }
 
    sprintf(szVolumeName, "\\\\.\\%c:", cDriveLetter);
 
    hVolume = CreateFile( szVolumeName,
                          dwAccessFlags,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          NULL,
                          OPEN_EXISTING,
                          0,
                          NULL );
 
    if (hVolume == INVALID_HANDLE_VALUE)
      printf("CreateFile error %d\n", GetLastError());
    return hVolume;
}
 
BOOL CloseVolume(HANDLE hVolume)
{
    return CloseHandle(hVolume);
}
 
BOOL LockVolume(HANDLE hVolume)
{
    DWORD dwBytesReturned;
    DWORD dwSleepAmount;
    int nTryCount;
 
    dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
 
    // Do this in a loop until a timeout period has expired
    for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
      if (DeviceIoControl(hVolume,
                          FSCTL_LOCK_VOLUME,
                          NULL0,
                          NULL0,
                          &dwBytesReturned,
                          NULL))
         return TRUE;
 
      Sleep(dwSleepAmount);
    }
    return FALSE;
}
 
BOOL DismountVolume(HANDLE hVolume)
{
    DWORD dwBytesReturned;
 
    return DeviceIoControl( hVolume,
                            FSCTL_DISMOUNT_VOLUME,
                            NULL0,
                            NULL0,
                            &dwBytesReturned,
                            NULL);
}
 
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
{
    DWORD dwBytesReturned;
    PREVENT_MEDIA_REMOVAL PMRBuffer;
 
    PMRBuffer.PreventMediaRemoval = fPreventRemoval;
 
    return DeviceIoControl( hVolume,
                            IOCTL_STORAGE_MEDIA_REMOVAL,
                            &PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
                            NULL0,
                            &dwBytesReturned,
                            NULL);
}
 
AutoEjectVolume(HANDLE hVolume)
{
    DWORD dwBytesReturned;
 
    return DeviceIoControl( hVolume,
                            IOCTL_STORAGE_EJECT_MEDIA,
                            NULL0,
                            NULL0,
                            &dwBytesReturned,
                            NULL);
}
 
BOOL EjectVolume(TCHAR cDriveLetter)
{
    HANDLE hVolume;
 
    BOOL fRemoveSafely = FALSE;
    BOOL fAutoEject = FALSE;
 
    hVolume = OpenVolume(cDriveLetter);
    if (hVolume == INVALID_HANDLE_VALUE)
      return FALSE;
 
    // Lock and dismount the volume.
    if (LockVolume(hVolume) && DismountVolume(hVolume)) {
      fRemoveSafely = TRUE;
      // Set prevent removal to false and eject the volume.
      if (PreventRemovalOfVolume(hVolume, FALSE) && AutoEjectVolume(hVolume))
        fAutoEject = TRUE;
    }
 
    // Close the volume so other processes can use the drive.
    if (!CloseVolume(hVolume))
      return FALSE;
 
    if (fAutoEject)
      printf("Media in Drive %c has been ejected safely.\n", cDriveLetter);
    else {
      if (fRemoveSafely)
        printf("Media in Drive %c can be safely removed.\n", cDriveLetter);
    }
    return TRUE;
}
 
void Usage()
{
    printf("Usage: Eject <drive letter>\n\n");
    return ;
}
 
void main(int argc, char * argv[])
{
    if (argc != 2) {
      Usage();
      return ;
    }
 
    if (!EjectVolume(argv[1][0]))
      printf("Failure ejecting drive %c.\n", argv[1][0]);
 
    return ;
}
cs


'연습' 카테고리의 다른 글

PowerShell CD Eject/Close 설정하는 방법.  (0) 2017.01.03
7z 사용법 -압축방법-  (0) 2017.01.02
최신 코덱인 AV1 현황.  (0) 2016.12.24
powershell 비프음 발생시키기.  (0) 2016.11.15
구글 드라이브 검색 사용법  (0) 2016.11.14
Posted by JunkMam
,

 MonkeyRunner을 이용해서 이미지를 분석할 수 있는데.(속도면에서 엄청 늦은 경우가 존재한다.)

 이것을 이용하기 위해서는 부분적으로 사진(이미지)을 잘라내서 사용하는 방법을 알아야 될 것이다.


 그래서 SubImage을 사용하는 방법을 작성하고자 한다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.awt.image.BufferedImage;
 
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
 
import com.android.chimpchat.adb.AdbChimpDevice;
 
import com.android.chimpchat.core.ChimpImageBase;
 
public class MonkeyTest {
    public static void main(String[] args) {
        
        IChimpDevice device = null;
        
        try
        {
            // sdk/platform-tools has to be in PATH env variable in order to find adb
            device = new AdbBackend().waitForConnection();            
        }
        catch(java.lang.NullPointerException e)
        {
            System.out.println("Error");
            System.exit(-1);
        }
        
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        IChimpImage subImage = device.takeSnapshot().getSubImage(4040250250);
        subImage.writeToFile("out.png""png");
        
        device.dispose();
        
        System.exit(0);
    }
}
cs



 여기서 getSubImage는


 x위치, y위치, 넓이, 높이 이런 순으로 작성하면 된다.


 단, 여기서 생성되는 사각형이 현재 이미지의 전체의 위치로 옮겨 가면 안된다.


 예을 들어서 가로 100, 세로 100인 이미지에서 x위치 99에 넓이 100 이렇게 하면, 오작동이 일어나게 된다.

Posted by JunkMam
,

 sameAs라는 메소드가 있고, 그것을 구현하는 내용을 한번 작성해봤다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import java.awt.image.BufferedImage;
 
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
 
import com.android.chimpchat.adb.AdbChimpDevice;
 
import com.android.chimpchat.core.ChimpImageBase;
 
public class MonkeyTest {
    public static void main(String[] args) {
        
        IChimpDevice device = null;
        
        try
        {
            // sdk/platform-tools has to be in PATH env variable in order to find adb
            device = new AdbBackend().waitForConnection();            
        }
        catch(java.lang.NullPointerException e)
        {
            System.out.println("Error");
            System.exit(-1);
        }
        
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        //device.takeSnapshot().writeToFile("out.png", "png");
        
        IChimpImage deviceImage = device.takeSnapshot();
        deviceImage.writeToFile("out_1.png""png");
        IChimpImage fileImage = ChimpImageBase.loadImageFromFile("out.png");
        fileImage.writeToFile("out_2.png""png");
        
        sameAs(fileImage,deviceImage,0.9);
        
        if(fileImage.sameAs(deviceImage, 0.75))
        {
            System.out.println("Sames");
        }
        else
        {
            System.out.println("Not");
        }
 
        device.dispose();
        
        System.exit(0);
    }
    
    public static boolean sameAs(IChimpImage other, IChimpImage sames, double percent){
        
        BufferedImage otherImage = other.getBufferedImage();
        BufferedImage samesImage = sames.getBufferedImage();
        
        //Easy size check
        if(otherImage.getWidth()!= samesImage.getWidth()){
            return false;
        }
        
        if(otherImage.getHeight()!=samesImage.getHeight()){
            return false;
        }
        
        int[] otherPixel = new int[1];
        int[] samesPixel = new int[1];
        
        int width = samesImage.getWidth();
        int height = samesImage.getHeight();
        
        int numDiffPixels = 0;
        // Now, go through pixel-by-pixel and check that the images are the same;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (samesImage.getRGB(x, y) != otherImage.getRGB(x, y)) {
                    System.out.println(samesImage.getRGB(x, y)+":"+otherImage.getRGB(x, y));
                    numDiffPixels++;
                }
            }
        }
        double numberPixels = (height * width);
        double diffPercent = numDiffPixels / numberPixels;
        
        return percent <= 1.0 - diffPercent;
    }
}
cs



 하지만, 왜 차이가 생기는지는 잘 모르겠다.


 값이 동일하게 나온 것이라고 생각하는데...


 일단, 이렇게 구현을 할 수 있다면, 특정 위치를 조작해서 처리할 수 있는 방법도 만들 수 있다.

Posted by JunkMam
,

 MonkeyRunner을 연결해서 사용하는 것이 있게 된다.


 여기서, 이미지를 받아 들이고, 이미지를 비교하는 소스를 제작했다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
 
import com.android.chimpchat.adb.AdbChimpDevice;
 
import com.android.chimpchat.core.ChimpImageBase;
 
public class MonkeyTest {
    public static void main(String[] args) {
        
        IChimpDevice device = null;
        
        try
        {
            // sdk/platform-tools has to be in PATH env variable in order to find adb
            device = new AdbBackend().waitForConnection();            
        }
        catch(java.lang.NullPointerException e)
        {
            System.out.println("Error");
            System.exit(-1);
        }
        
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        //device.takeSnapshot().writeToFile("out.png", "png");
        
        IChimpImage deviceImage = device.takeSnapshot();
        deviceImage.writeToFile("out_1.png""png");
        IChimpImage fileImage = ChimpImageBase.loadImageFromFile("out.png");
        fileImage.writeToFile("out_2.png""png");
        
        if(fileImage.sameAs(deviceImage, 0.75))
        {
            System.out.println("Sames");
        }
        else
        {
            System.out.println("Not");
        }
 
        device.dispose();
        
        System.exit(0);
    }
}
cs


 여기서 sameAs라는 것에서 1.0에 가까우면, 원본이랑 동일하게 보는 것이 맞다. 하지만, 제대로 동작이 안되는 경우가 있다.


 여기서, MonkeyRunner라는 분석이라고하여서 해당 소스를 올린 블로그가 있다.


 참조하면 도움이 될 것이다.


 http://goodtogreate.tistory.com/entry/monkeyrunner%EC%9D%98-%EB%B6%84%EC%84%9D

Posted by JunkMam
,

 MonkeyRunner를 Java에 연결해서 사용이 가능하다. 라는 식으로 예제 소스와 내용을 설명해주었다.


 이것을 제대로 Java의 소스를 작성하는 방법을 포스팅 할려고 한다.


 먼저, Eclipse을 이용해서 Java Project을 만들어 놓는다.



 프로젝트에서 Properties(환경 설정)에 들어가서 환경을 설정하는 창을 띄운다.



 여기서 Java Build Path(Java에서 Library등을 가지고오게하는 설정이다.)에서 들어가면, Library을 설정할 수 있는 탭이 있다.(이미 추가를 시킨 상태이다.)


 여기서 [Android SDK 경로]\tools\lib\MonkeyRunner.jar 을 가지고온다.


 여기서 MonkeyRunner라는 것은 공개 소스로 제작되어 있는 부분이 있다.(그리고 MonkeyRunner가 아닌, chimpchat.jar을 가지고와서 사용하는게 더 올바른 방식이다.


 MonkeyRunner는 Java + Python인 상태이기 때문에, Python의 정보를 가지고 있지 않는다면, 사용을 제대로 할 수 없는 것을 알 수 있다.

 하지만, MonkeyRunner에서 있는 Python을 분석해서 chimpchar에게 정보를 보내는것을 알 수 있기 때문에, 다음 링크를 읽으면서 분석하면, 이해에 도움이 될 것이다.


 링크 : https://android.googlesource.com/platform/tools/swt/+/android-4.4_r1.1/monkeyrunner/src/main/java/com/android/monkeyrunner


 이제, 다음과 같은 소스를 보여주면서, 자세하게 설명을 하도록 하겠다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
 
public class MonkeyTest {
    public static void main(String[] args) {
        IChimpDevice device = null;
        try
        {
            // sdk/platform-tools has to be in PATH env variable in order to find adb
            device = new AdbBackend().waitForConnection();            
        }
        catch(java.lang.NullPointerException e)
        {
            System.out.printf("Error");
            System.exit(-1);
        }
 
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        device.takeSnapshot().writeToFile("out.png""png");
 
        device.dispose();
        
        System.exit(0);
    }
}
cs


 이것에서 device라는 것은 ChimpDevice라는 것으로, Adb에 연결하는 방식으로,


 Python에서 있는 MonkeyDevice와 비슷하다고 보면, 이해가 될 것이다.


 MonkeyRunner는 AdbBackend라는 클래스와 동일하다고 보면 될 것이다.


 AdbBackend라는 클래스는 ADB와 연결되서 통신하는 클래스이다.


 여기서, waitForConnection은 2가지의 함수가 존재하는데.


 waitForConnection()과 waitForConnection(String)이 있다.


 여기서 String에는 ADB에서 있는 Device의 명칭을 작성하면, 해당 Device을 연결 할 수 있게 된다.


 여기서 device의 정보를 얻기 위해서는 ddmuilib이라는 것을 이용해야된다.


 거기에 대해서는 또 다른 방법을 찾아야 될 것이므로, 나중에 하도록 한다.


 Adb의 정보가 없다면, NullPointerException이라는 오류가 발생하는 경우가 있다.

 이 경우에 예외 처리하는게 좋다.


 현재 Device의 명칭을 알기 위해서 device.getProperty을 이용해서 알아보게 만들 수 있으며.


 device.takeSnapshot()을 이용해서 그림을 가지고 올 수 있다.


 writeToFile(String1, String2)에서 String1은 파일 명칭/경로를 뜻하는 것이고, String2는 파일의 포맷이다. 기본적으로 PNG을 기본적으로 가지고 있으며, PNG을 제외한, JPG가 적용이 가능하다.


 device.dispose();는 연결을 끊는 것이다.


 윗 방식을 이용하면, 스샷을 찍어서 png 포맷을 가진 out.png 파일이 생성된다.

Posted by JunkMam
,

 안드로이드 SDK을 업그레이드 혹은 설치하면서 자동으로 설치되는 것이 MonkeyRunner라고 했다.


 이것을 Java에 연결할 수도 있는데, 그 이유는 jar로 MonkeyRunner을 설정해놓았기 때문이다.


 MonkeyRunner는 python와 Java을 같이 연결해서 사용하는 방식으로 Jython이라는 것이다.


 그래서 MonkeyRunner.bat을 이용해서 Python으로 구성한 소스를 동작 시킬 수 있게 할 수 있다.


 Java을 MonkeyRunner로 연결하기 위해서 다음 링크를 보면 도움이 될 것이다.


 링크 : http://stackoverflow.com/questions/6686085/how-can-i-make-a-java-app-using-the-monkeyrunner-api


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
 
public class MonkeyTest {
    public static void main(String[] args) {
        // sdk/platform-tools has to be in PATH env variable in order to find adb
        IChimpDevice device = new AdbBackend().waitForConnection();
 
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        device.takeSnapshot().writeToFile("out.png"null);
 
        device.dispose();
    }
}
cs


 윗 예시 소스는 윗 링크에서 가지고온 소스이다.


 여기서, MonkeyRunner가 아닌, MonkeyDevice라는 게 있다.


 원래, MonkeyRunner라는 것은 ADB을 연결해서 처리해주는 중간자 역할을 하는 클래스다.


 그래서 MonkeyRunner을 사용해도 되고, adb을 바로 연결하는 AdbBackend라는 녀석을 사용해도 된다.


 나머지는 MonkeyRunner의 예시와 유사하다.


 단, 연결을 끊고 다시 연결하는 행위를 할 수 있다.(MonkeyRunner는 Python을 다 읽고 난 후에 알아서 종료하게 된다.)


Posted by JunkMam
,

 요즘 바빠서 연습삼아서 간단한 코딩을 해봤다.


 이미 있는 파일 방식이라서 별 어려움도 없을 뿐더러. 딱히 제대로 사용이 될 것 같지만, 단일 파일의 길이를 알아봐야 되는 일이 있을 것이다.


 단일 파일의 길이를 알아야 되는 것은 파일을 읽었을때, 메모리 초과를 일어날 수 도 있고, 다양한 이유가 있을 것이다.


 파일의 길이를 알아 내는 것은 간단한 함수를 사용하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#include <stdlib.h>
 
long getFileSize(FILE*);
 
int main()
{
    FILE *filePoint = NULL;
    long fileSize = 0;
 
    if((filePoint=fopen("./test.txt","r"))==NULL)
    {
        printf("Error : File Not Files");
        return -1;
    }
 
    fileSize = getFileSize(filePoint);
 
    printf("File Size : %d", fileSize);
 
    return 0;
}
 
long getFileSize(FILE *filePoint)
{
    long fileSize = 0;
    fseek(filePoint, 0L, SEEK_END);
    fileSize = ftell(filePoint);
    fclose(filePoint);
 
    return fileSize;
}
 
cs


 fileSize라는 것으로 파일의 길이를 얻을 수 있다.


 여기서 사용하는 함수는 2가지인데, 첫번째는 fseek이다.


 fseek라는 것은 파일을 읽는 포인터의 위치를 개발자가 자기 원하는 형태로 바꾸는 것이다.


 단일 파일의 길이를 알아내는 방법은 간단하게 파일의 끝으로 파일 포인트를 보낸 다음에, 그 위치를 읽으면 된다.


 그래서 단일 파일에서 파일 끝으로 보내는 방법으로


 fseek(filePoint, 0L, SEEK_END); 을 사용한다.


 이 후에 ftell을 사용한다.


 ftell은 파일 포인터 위치의 값을 반환해주는 함수이다.


 fseek(filePoint, 0L, SEEK_END);을 한 후에라면, 파일 포인터의 위치의 값이 파일의 끝을 되게 된다. 그래서 ftell은 파일의 끝이 출력되어 파일의 최대 크기가 받아 지게 된다.


 하지만, 이건 잘 쓰일 일이 없다.


 이유는 sys/stat.h을 사용하면, 이상없이 사용이 가능하기 때문이다.


 stat 구조체에서 파일의 크기를 가지고 있기 때문에, 굳이 단일 파일을 열어서 관리할 필요가 없다는 것이다.


 하지만, 단일 파일의 크기를 이용해서 쓰거나 읽어 들이는 용도로는 쓸만 한 것 같다.

Posted by JunkMam
,


1
2
3
forceinline bool isPowerOf2(uint32_t n){
return(n&(n-1))==0;
}
cs


 isPowerOf2은 2의 제곱인지 확인 하는 것이다.


 여기서 본다면, n이 2의 제곱인가에 대해서 확인하는 함수이다.


 이걸 이해하기위해서는 2의 진법에 대해서 알고 있으면 아주 쉽게 표현이 가능하다.


 컴퓨터는 전기로 흐르는 장치이다. 그래서 2의 진법으로 컴퓨터의 숫자가 표현이 된다. 이걸 이용해서 2의 제곱인지를 확인 할 수 있다.


 예을 들어서 2라고 한다면, 10(2)라는 이진수가 표현이 된다.


 여기서 10(2) and 01(2)이 된다면, 동일한 숫자가 없기 때문에, 0이 된다.


 반대로 3인 11(2) and 10(2)가 되면, 1이 나오기 때문에, 0이 되지 않는다.


 동일하게 4와 5을 해보면,


 4일때,

 100(2) and 011(2) 가 되서, 0이 되지만,


 5일때,

 101(2) and 100(2) 가 되서, 0이 되지 않는다.


 이걸 이용해서 3의 제곱이나 그런게 되는지 확인해봤지만, 제대로 되지 않았다.


 4, 8, 16등은 전부다 2의 제곱들이기 때문에, 저 소스로 제곱으로 확인을 할 수 있다는건 알 수 있을 것이다.


 

1
2
3
4
5
forceinline uint bitSize(uint Value){
uint Total=0;
for(;Value;Value>>=1,Total++);
return Total;
}
cs


 이것은 bit크기를 확인하는 함수이다.


 보면, Total은 result이다.


 컴퓨터는 0이면 거짓, 0이외의 값을 가진다면 참으로 처리한다. 그래서 for문에서 조건부분이 들어가는 곳에서 Value만 들어가 있는 것이다.


 그리고 반복에서 Value>>=1은 다시 풀어 적으면, Value = Value >> 1이라는 것으로 우측으로 1bit씩 이동시키는 것이다.


 Total은 그 bit의 갯수를 기록하기 위한 것이고 말이다.


 아직 실력이 부족해서 그런지 완벽하게 분석하는데 시간이 걸리는 것 같다.

 조금 시간을 들여서 더 자세하게 기록을 해야 겠다.

Posted by JunkMam
,

 Util.hpp에 대해서 대충 설명을 하고 넘겼다.


 어떻게 동작하고 되는지 설명을 작성할려고한다.


 

1
2
3
4
5
#ifdef WIN32
#define forceinline __forceinline
#else
#define forceinline inline __attribute__((always_inline))
#endif
cs

 처음에 이렇게 되어 있는게 있다.

 WIN32이란, 컴파일러에 정의되어있는 매크로이다.
 이것은 Win32에 컴파일을 하기 위해서 사용하는 것이다.(Windows OS에서 컴파일을 하지 않을 경우란, 리눅스에서 사용할 경우가 해석이 될 수 있다.)

 __forceinline이라는 것이 있다. 이것은 인라인 함수이다.[각주:1]


 설명을 본다면, 함수의 속도를 높이기 위해서 사용을 한다.[각주:2][각주:3]


 일반적인 함수는 사용할때마다 호출하므로 제어권의 이동이 심해서 실행 속도가 느려진다고 한다. 그리고 데이터형 체크를 할 수 있어서, 오버헤드를 줄인다고 하낟.


 단점은 실행 파일이 커진다고 한다.


 더 자세한 것은 참조 블로그를 읽으면서 확인하길 바란다.


 그래서 Win32(윈도우 운영체제일 경우)에 인라인 함수 매크로로 정의를 시킨다.(다음 소스에서 자주 사용이 된다.)


1
2
3
4
5
6
7
forceinline static bool isUpperCase(int c){
 return c>='A'&&c<='Z';
}
 
forceinline static bool isLowerCase(int c){
 return c>='a'&&c<='z';
}
cs

 isUpperCase랑 isLowerCase는 해당 영문을 받아들여서 대문자인지 소문자인지 알아보는 소스이다.
 여기서 알아야 될 것은 ASCII이다.
 컴퓨터는 모든 데이터를 숫자로 알고 있다.
 그래서 ASCII에서 내용 또한 숫자가 될 수 있고, 문자가 될 수 있다.(출력할때, 문자인지 아닌지 확인해서 처리하는 방식으로 우리가 문자를 출력해준다.)

 그래서 ASCII의 표를 읽어본다면, 대문자의 범위와 소문자의 범위가 있고, 그것을 참과 거짓으로 출력하는 함수이다.

1
2
3
forceinline static bool isWordChar(int c){
 return isLowerCase(c)||isUpperCase(c)||c>=128;
}
cs


 isWordChar 또한, ASCII을 분석하면 나오는 것이다.

 여기서 ASCII는 최대 128가지의 문자만 정의되어 있고, 그 이상은 ASCII에 정의되지 않은 숫자 데이터이다.(이걸 이용해서 UNICODE등을 사용할때, 128초과되는 수를 앞에 사용한다.)


 그래서, 이걸 이용해서 문자인지 아닌지 확인을 한다.(단, 영문이라는 보장은 없다.)


1
2
3
4
5
6
7
8
9
forceinline static int makeLowerCase(int c){
 assert(isUpperCase(c));
 return c-'A'+'a';
}
 
forceinline static int makeUpperCase(int c){
 assert(isLowerCase(c));
 return c-'a'+'A';
}
cs

 makeLowerCase와 makeUpperCase는 대문자를 소문자로, 소문자를 대문자로 만드는 함수이다.

 여기서 assert는 사용자에게 작동을 하다가 오류가 발생하면, 알려주는 작업을 하는 매크로 함수이다.

 #include<cassert> 라는 헤더(assert.h와 동일한 헤더이다.)에서 정의되어 있는 함수이다.

 0을 준다면, 문제가 발생. 0이외의 값을 준다면, 문제가 없음.으로 처리한다.
 이것은 release 모드(실행 파일 생성)일때, 컴파일을 멈춰준다. 그래서 개발자가 어디에서 오류가 났는지 알 수 있게 도움을 줄 수 있다.

 c-'A'+'a'; 라는 것은 일단, 컴퓨터는 모든 데이터가 숫자라고 했다. 'A' 또한, ASCII에서 'A'을 정의된 숫자이다. 그래서 c-'A'처럼 계산이 가능하게 된다.

 c가 'D'라고 가정하자.(여기서 c가 소문자일 경우엔, assert 함수에 의해서 오류가 발생하게 된다.)
 'A'와 'D'의 거리는 4만큼 차이가 나게 된다. 여기서 'a'을 더하게 되면, 'a'의 기준으로 4만큼 간 값이 되기 때문에 'd'가 나오게 된다.

 makeUpperCase 또한 동일한 방식으로 계산이 되는 것이다.

 만약에 c가 대/소문자에 들어가 있지 않다면, assert에 의해서 오류가 발생하게 된다.

 일부는 나중에 더 적는걸로...


  1. 참조 : https://msdn.microsoft.com/ko-kr/library/bw1hbe6y.aspx(2016-07-19) [본문으로]
  2. 인라인 함수 특징과 장단점을 설명하는 블로그 : http://blog.naver.com/PostView.nhn?blogId=sendmade&logNo=80200881136&redirect=Dlog&widgetTypeCall=true [본문으로]
  3. 인라인 함수 특징과 장단점 : http://blog.naver.com/PostView.nhn?blogId=sendmade&logNo=80200881136&redirect=Dlog&widgetTypeCall=true (2016-07-19) [본문으로]
Posted by JunkMam
,