【Android】Javaでハッシュ値を計算するアプリを作ってみた（SHA256）

# 雰囲気

なんか、
![Screenshot_20201126-222656.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188881/0033a147-5904-7541-2ce1-c9cb96ac467e.png)

こんな感じで動く。
![Screenshot_20201126-222702.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188881/29f35b06-0f6b-acf0-ae69-ac055df843c9.png)


# 環境

Windows10
AndroidStudio 3.5.0.0
Android SDK 26.1.1
(Pixel OS10で動作確認)

# MainActivity.java

```java
package com.weare2434.sha256;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.app.AlertDialog;
import java.security.MessageDigest;

public class MainActivity extends AppCompatActivity {
    private EditText editText;
    private Button button;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
        button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(R.id.textView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String text = editText.getText().toString();
                if (!text.equals("")){
                    textView.setText(text);
                    editText.setText("");
                    
                    //SHA256
                    byte[] cipher_byte;
                    try {
                        MessageDigest md = MessageDigest.getInstance("SHA-256");
                        md.update(text.getBytes());
                        cipher_byte = md.digest();
                        StringBuilder sb = new StringBuilder(2 * cipher_byte.length);
                        for(byte b: cipher_byte) {
                            sb.append(String.format("%02x", b&0xff) );
                        }
                        text = String.valueOf(sb);

                        //クリップボードにテキストを保存
                        ClipboardManager clipboard = (ClipboardManager)
                                getSystemService(Context.CLIPBOARD_SERVICE);
                        clipboard.setPrimaryClip(ClipData.newPlainText("", text));

                        Toast.makeText(view.getContext(), text, Toast.LENGTH_SHORT).show();

                        new AlertDialog.Builder(view.getContext())
                                .setTitle("")
                                .setMessage("ハッシュ値：\n" + text + "\n計算成功！クリップボードにコピーしました。")
                                .setPositiveButton("close", null)
                                .show();
                        text = "計算成功！";
                    } catch (Exception e) {
                        text = "計算失敗！";
                        Toast.makeText(view.getContext(), text, Toast.LENGTH_SHORT).show();

                        new AlertDialog.Builder(view.getContext())
                                .setTitle("")
                                .setMessage(text)
                                .setPositiveButton("close", null)
                                .show();
                    }
                    textView.setText(text);
                }
                else {
                    Toast.makeText(view.getContext(), "入力してください", Toast.LENGTH_SHORT).show();
                    textView.setText("No Input");
                }
            }
        });

        //textViewコピー有効
        textView.setTextIsSelectable(true); // Text Selection をenableにする
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            textView.setCustomSelectionActionModeCallback(new ActionMode.Callback2() {
                @Override
                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                    return true;
                }

                @Override
                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                    return false;
                }

                @Override
                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

                    switch (item.getItemId()) {
                        case android.R.id.copy:
                            int min = 0;
                            int max = textView.getText().length();
                            if (textView.isFocused()) {
                                final int selStart = textView.getSelectionStart();
                                final int selEnd = textView.getSelectionEnd();

                                min = Math.max(0, Math.min(selStart, selEnd));
                                max = Math.max(0, Math.max(selStart, selEnd));
                            }

                            final CharSequence selectedText = textView.getText()
                                    .subSequence(min, max);
                            String text = selectedText.toString();

                            ClipboardManager clipboard = (ClipboardManager)
                                    getSystemService(Context.CLIPBOARD_SERVICE);
                            clipboard.setPrimaryClip(ClipData.newPlainText("", text));

                            // ActionModeの終了
                            mode.finish();
                            return true;
                        case android.R.id.cut:
                            return true;
                        case android.R.id.paste:
                            return true;

                        default:
                            break;
                    }
                    return false;
                }

                @Override
                public void onDestroyActionMode(ActionMode mode) {
                }
            });
        }
    }
}

```



# activity_main.xml

```xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.weare2434.sha256.MainActivity">


    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="156dp"
        android:ems="13"
        android:inputType="textMultiLine"
        android:hint="Please Input Text"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="90dp"
        android:text="No Input" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:text="calc HASH"
        android:id="@+id/button"/>
</RelativeLayout>
```

# 素晴らしすぎるコピペ元様（順不同、多謝）

[JavaでSHA256を計算する - Java入門](
https://kaworu.jpn.org/java/Java%E3%81%A7SHA256%E3%82%92%E8%A8%88%E7%AE%97%E3%81%99%E3%82%8B)

[【Android】クリップボードにコピーする - Qiita](https://qiita.com/CUTBOSS/items/97669c712449510fe7f0)

[[Android] EditText をコードで記述する - nyan のアプリ開発](https://akira-watson.com/android/edittext-code.html)

[【Android】EditTextでの文字の複数行入力とInputTypeの種類](https://cpoint-lab.co.jp/article/201811/6267/)